Factor out SessionController from BasicUI

Towards sharing this code with ARDOUR_UI.
This commit is contained in:
David Robillard 2021-06-17 11:02:08 -04:00
parent 8998efa8c8
commit 1559829e24
24 changed files with 1050 additions and 849 deletions

View file

@ -160,15 +160,15 @@ CC121::CC121 (Session& s)
get_button (EButton).set_action (boost::bind (&CC121::touch, this), true); get_button (EButton).set_action (boost::bind (&CC121::touch, this), true);
get_button (OpenVST).set_action (boost::bind (&CC121::off, this), true); get_button (OpenVST).set_action (boost::bind (&CC121::off, this), true);
get_button (Play).set_action (boost::bind (&BasicUI::transport_play, this, true), true); get_button (Play).set_action (boost::bind (&SessionController::transport_play, _controller, true), true);
get_button (ToStart).set_action (boost::bind (&BasicUI::prev_marker, this), true); get_button (ToStart).set_action (boost::bind (&SessionController::prev_marker, _controller), true);
get_button (ToEnd).set_action (boost::bind (&BasicUI::next_marker, this), true); get_button (ToEnd).set_action (boost::bind (&SessionController::next_marker, _controller), true);
get_button (RecEnable).set_action (boost::bind (&BasicUI::rec_enable_toggle, this), true); get_button (RecEnable).set_action (boost::bind (&SessionController::rec_enable_toggle, _controller), true);
get_button (Stop).set_action (boost::bind (&BasicUI::transport_stop, this), true); get_button (Stop).set_action (boost::bind (&SessionController::transport_stop, _controller), true);
get_button (Ffwd).set_action (boost::bind (&BasicUI::ffwd, this), true); get_button (Ffwd).set_action (boost::bind (&SessionController::ffwd, _controller), true);
get_button (Rewind).set_action (boost::bind (&BasicUI::rewind, this), true); get_button (Rewind).set_action (boost::bind (&SessionController::rewind, _controller), true);
get_button (Loop).set_action (boost::bind (&BasicUI::loop_toggle, this), true); get_button (Loop).set_action (boost::bind (&SessionController::loop_toggle, _controller), true);
get_button (Jog).set_action (boost::bind (&CC121::jog, this), true); get_button (Jog).set_action (boost::bind (&CC121::jog, this), true);
get_button (Mute).set_action (boost::bind (&CC121::mute, this), true); get_button (Mute).set_action (boost::bind (&CC121::mute, this), true);
@ -669,7 +669,7 @@ CC121::map_transport_state ()
{ {
get_button (Loop).set_led_state (_output_port, _session->get_play_loop()); get_button (Loop).set_led_state (_output_port, _session->get_play_loop());
float ts = get_transport_speed(); float ts = _controller.get_transport_speed();
if (ts == 0) { if (ts == 0) {
stop_blinking (Play); stop_blinking (Play);

View file

@ -574,9 +574,9 @@ ContourDesignControlProtocol::jump_forward (JumpDistance dist)
{ {
LocateTransportDisposition kr = _keep_rolling ? RollIfAppropriate : MustStop; LocateTransportDisposition kr = _keep_rolling ? RollIfAppropriate : MustStop;
switch (dist.unit) { switch (dist.unit) {
case SECONDS: jump_by_seconds (dist.value, kr); break; case SECONDS: _controller.jump_by_seconds (dist.value, kr); break;
case BEATS: jump_by_beats (dist.value, kr); break; case BEATS: _controller.jump_by_beats (dist.value, kr); break;
case BARS: jump_by_bars (dist.value, kr); break; case BARS: _controller.jump_by_bars (dist.value, kr); break;
default: break; default: break;
} }
} }
@ -607,17 +607,17 @@ ContourDesignControlProtocol::shuttle_event (int position)
if (position != 0) { if (position != 0) {
if (_shuttle_was_zero) { if (_shuttle_was_zero) {
_was_rolling_before_shuttle = transport_rolling (); _was_rolling_before_shuttle = _controller.transport_rolling ();
} }
const vector<double>& spds = _shuttle_speeds; const vector<double>& spds = _shuttle_speeds;
const double speed = position > 0 ? spds[position-1] : -spds[-position-1]; const double speed = position > 0 ? spds[position-1] : -spds[-position-1];
set_transport_speed (speed); _controller.set_transport_speed (speed);
_shuttle_was_zero = false; _shuttle_was_zero = false;
} else { } else {
if (_keep_rolling && _was_rolling_before_shuttle) { if (_keep_rolling && _was_rolling_before_shuttle) {
set_transport_speed (1.0); _controller.set_transport_speed (1.0);
} else { } else {
transport_stop (); _controller.transport_stop ();
} }
_shuttle_was_zero = true; _shuttle_was_zero = true;
} }

View file

@ -42,6 +42,7 @@ PBD::Signal2<void,std::string,std::string> BasicUI::AccessAction;
BasicUI::BasicUI (Session& s) BasicUI::BasicUI (Session& s)
: _session (&s) : _session (&s)
, _controller (&s)
{ {
} }
@ -69,226 +70,6 @@ BasicUI::access_action ( std::string action_path )
AccessAction( group, item ); AccessAction( group, item );
} }
void
BasicUI::loop_toggle ()
{
if (!_session) {
return;
}
Location * looploc = _session->locations()->auto_loop_location();
if (!looploc) {
return;
}
if (_session->get_play_loop()) {
/* looping enabled, our job is to disable it */
_session->request_play_loop (false);
} else {
/* looping not enabled, our job is to enable it.
loop-is-NOT-mode: this action always starts the transport rolling.
loop-IS-mode: this action simply sets the loop play mechanism, but
does not start transport.
*/
if (Config->get_loop_is_mode()) {
_session->request_play_loop (true, false);
} else {
_session->request_play_loop (true, true);
}
}
//show the loop markers
looploc->set_hidden (false, this);
}
void
BasicUI::loop_location (samplepos_t start, samplepos_t end)
{
Location* tll;
if ((tll = _session->locations()->auto_loop_location()) == 0) {
Location* loc = new Location (*_session, start, end, _("Loop"), Location::IsAutoLoop);
_session->locations()->add (loc, true);
_session->set_auto_loop_location (loc);
} else {
tll->set_hidden (false, this);
tll->set (start, end);
}
}
void
BasicUI::goto_start (bool and_roll)
{
_session->goto_start (and_roll);
}
void
BasicUI::goto_zero ()
{
_session->request_locate (0);
}
void
BasicUI::goto_end ()
{
_session->goto_end ();
}
void
BasicUI::add_marker (const std::string& markername)
{
samplepos_t where = _session->audible_sample();
Location *location = new Location (*_session, where, where, markername, Location::IsMark);
_session->begin_reversible_command (_("add marker"));
XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state();
_session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
_session->commit_reversible_command ();
}
void
BasicUI::remove_marker_at_playhead ()
{
if (_session) {
//set up for undo
XMLNode &before = _session->locations()->get_state();
bool removed = false;
//find location(s) at this time
Locations::LocationList locs;
_session->locations()->find_all_between (_session->audible_sample(), _session->audible_sample()+1, locs, Location::Flags(0));
for (Locations::LocationList::iterator i = locs.begin(); i != locs.end(); ++i) {
if ((*i)->is_mark()) {
_session->locations()->remove (*i);
removed = true;
}
}
//store undo
if (removed) {
_session->begin_reversible_command (_("remove marker"));
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
_session->commit_reversible_command ();
}
}
}
void
BasicUI::button_varispeed (bool fwd)
{
// incrementally increase speed by semitones
// (keypress auto-repeat is 100ms)
const float maxspeed = Config->get_shuttle_max_speed();
float semitone_ratio = exp2f (1.0f/12.0f);
const float octave_down = pow (1.0/semitone_ratio, 12.0);
float transport_speed = get_transport_speed ();
float speed;
if (Config->get_rewind_ffwd_like_tape_decks()) {
if (fwd) {
if (transport_speed <= 0) {
_session->request_transport_speed (1.0, false);
_session->request_roll (TRS_UI);
return;
}
} else {
if (transport_speed >= 0) {
_session->request_transport_speed (-1.0, false);
_session->request_roll (TRS_UI);
return;
}
}
} else {
if (fabs (transport_speed) <= 0.1) {
/* close to zero, maybe flip direction */
if (fwd) {
if (transport_speed <= 0) {
_session->request_transport_speed (1.0, false);
_session->request_roll (TRS_UI);
}
} else {
if (transport_speed >= 0) {
_session->request_transport_speed (-1.0, false);
_session->request_roll (TRS_UI);
}
}
/* either we've just started, or we're moving as slowly as we
* ever should
*/
return;
}
if (fwd) {
if (transport_speed < 0.f) {
if (fabs (transport_speed) < octave_down) {
/* we need to move the speed back towards zero */
semitone_ratio = powf (1.f / semitone_ratio, 4.f);
} else {
semitone_ratio = 1.f / semitone_ratio;
}
} else {
if (fabs (transport_speed) < octave_down) {
/* moving very slowly, use 4 semitone steps */
semitone_ratio = powf (semitone_ratio, 4.f);
}
}
} else {
if (transport_speed > 0.f) {
/* we need to move the speed back towards zero */
if (transport_speed < octave_down) {
semitone_ratio = powf (1.f / semitone_ratio, 4.f);
} else {
semitone_ratio = 1.f / semitone_ratio;
}
} else {
if (fabs (transport_speed) < octave_down) {
/* moving very slowly, use 4 semitone steps */
semitone_ratio = powf (semitone_ratio, 4.f);
}
}
}
}
speed = semitone_ratio * transport_speed;
speed = std::max (-maxspeed, std::min (maxspeed, speed));
_session->request_transport_speed (speed, false);
_session->request_roll (TRS_UI);
}
void
BasicUI::rewind ()
{
button_varispeed (false);
}
void
BasicUI::ffwd ()
{
button_varispeed (true);
}
void
BasicUI::transport_stop ()
{
_session->request_stop ();
}
bool bool
BasicUI::stop_button_onoff () const BasicUI::stop_button_onoff () const
{ {
@ -298,19 +79,19 @@ BasicUI::stop_button_onoff () const
bool bool
BasicUI::play_button_onoff () const BasicUI::play_button_onoff () const
{ {
return get_transport_speed() == 1.0; return _controller.get_transport_speed() == 1.0;
} }
bool bool
BasicUI::ffwd_button_onoff () const BasicUI::ffwd_button_onoff () const
{ {
return get_transport_speed() > 1.0; return _controller.get_transport_speed() > 1.0;
} }
bool bool
BasicUI::rewind_button_onoff () const BasicUI::rewind_button_onoff () const
{ {
return get_transport_speed() < 0.0; return _controller.get_transport_speed() < 0.0;
} }
bool bool
@ -319,129 +100,6 @@ BasicUI::loop_button_onoff () const
return _session->get_play_loop(); return _session->get_play_loop();
} }
void
BasicUI::transport_play (bool from_last_start)
{
/* ::toggle_roll() is smarter and preferred */
if (!_session) {
return;
}
if (_session->is_auditioning()) {
return;
}
bool rolling = transport_rolling();
if (_session->get_play_loop()) {
/* If loop playback is not a mode, then we should cancel
it when this action is requested. If it is a mode
we just leave it in place.
*/
if (!Config->get_loop_is_mode()) {
/* XXX it is not possible to just leave seamless loop and keep
playing at present (nov 4th 2009)
*/
if (rolling) {
/* stop loop playback but keep rolling */
_session->request_play_loop (false, false);
}
}
} else if (_session->get_play_range () ) {
/* stop playing a range if we currently are */
_session->request_play_range (0, true);
}
if (rolling) {
_session->request_transport_speed (1.0, false, TRS_UI);
} else {
_session->request_roll ();
}
}
void
BasicUI::rec_enable_toggle ()
{
switch (_session->record_status()) {
case (RecordState)Disabled:
if (_session->ntracks() == 0) {
// string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
// MessageDialog msg (*editor, txt);
// msg.run ();
return;
}
_session->maybe_enable_record ();
break;
case (RecordState)Recording:
case (RecordState)Enabled:
_session->disable_record (false, true);
}
}
void
BasicUI::all_tracks_rec_in ()
{
_session->set_all_tracks_record_enabled (true);
}
void
BasicUI::all_tracks_rec_out ()
{
_session->set_all_tracks_record_enabled (false);
}
void
BasicUI::save_state ()
{
_session->save_state ("");
}
void
BasicUI::prev_marker ()
{
samplepos_t pos = _session->locations()->first_mark_before (_session->transport_sample());
if (pos >= 0) {
_session->request_locate (pos);
} else {
_session->goto_start ();
}
}
void
BasicUI::next_marker ()
{
samplepos_t pos = _session->locations()->first_mark_after (_session->transport_sample());
if (pos >= 0) {
_session->request_locate (pos);
} else {
_session->goto_end();
}
}
void
BasicUI::set_transport_speed (double speed)
{
_session->request_transport_speed (speed);
}
double
BasicUI::get_transport_speed () const
{
return _session->actual_speed ();
}
double
BasicUI::transport_rolling () const
{
return !_session->transport_stopped_or_stopping ();
}
void void
BasicUI::undo () BasicUI::undo ()
{ {
@ -454,227 +112,6 @@ BasicUI::redo ()
access_action ("Editor/redo"); access_action ("Editor/redo");
} }
void
BasicUI::toggle_all_rec_enables ()
{
if (_session->get_record_enabled()) {
// _session->record_disenable_all ();
} else {
// _session->record_enable_all ();
}
}
void
BasicUI::toggle_punch_in ()
{
_session->config.set_punch_in (!_session->config.get_punch_in());
}
void
BasicUI::toggle_punch_out ()
{
_session->config.set_punch_out (!_session->config.get_punch_out());
}
bool
BasicUI::get_record_enabled ()
{
return _session->get_record_enabled();
}
void
BasicUI::set_record_enable (bool yn)
{
if (yn) {
_session->maybe_enable_record ();
} else {
_session->disable_record (false, true);
}
}
samplepos_t
BasicUI::transport_sample ()
{
return _session->transport_sample();
}
void
BasicUI::locate (samplepos_t where, LocateTransportDisposition ltd)
{
_session->request_locate (where, ltd);
}
void
BasicUI::locate (samplepos_t where, bool roll)
{
_session->request_locate (where, roll ? MustRoll : RollIfAppropriate);
}
void
BasicUI::jump_by_seconds (double secs, LocateTransportDisposition ltd)
{
samplepos_t current = _session->transport_sample();
double s = (double) current / (double) _session->nominal_sample_rate();
s+= secs;
if (s < 0) {
s = 0;
}
s = s * _session->nominal_sample_rate();
_session->request_locate (floor(s), ltd);
}
void
BasicUI::jump_by_bars (double bars, LocateTransportDisposition ltd)
{
TempoMap& tmap (_session->tempo_map());
Timecode::BBT_Time bbt (tmap.bbt_at_sample (_session->transport_sample()));
bars += bbt.bars;
if (bars < 0) {
bars = 0;
}
AnyTime any;
any.type = AnyTime::BBT;
any.bbt.bars = bars;
_session->request_locate (_session->convert_to_samples (any), ltd);
}
void
BasicUI::jump_by_beats (double beats, LocateTransportDisposition ltd)
{
TempoMap& tmap (_session->tempo_map ());
double qn_goal = tmap.quarter_note_at_sample (_session->transport_sample ()) + beats;
if (qn_goal < 0.0) {
qn_goal = 0.0;
}
_session->request_locate (tmap.sample_at_quarter_note (qn_goal), ltd);
}
void
BasicUI::toggle_monitor_mute ()
{
if (_session->monitor_out()) {
boost::shared_ptr<MonitorProcessor> mon = _session->monitor_out()->monitor_control();
if (mon->cut_all ()) {
mon->set_cut_all (false);
} else {
mon->set_cut_all (true);
}
}
}
void
BasicUI::toggle_monitor_dim ()
{
if (_session->monitor_out()) {
boost::shared_ptr<MonitorProcessor> mon = _session->monitor_out()->monitor_control();
if (mon->dim_all ()) {
mon->set_dim_all (false);
} else {
mon->set_dim_all (true);
}
}
}
void
BasicUI::toggle_monitor_mono ()
{
if (_session->monitor_out()) {
boost::shared_ptr<MonitorProcessor> mon = _session->monitor_out()->monitor_control();
if (mon->mono()) {
mon->set_mono (false);
} else {
mon->set_mono (true);
}
}
}
void
BasicUI::midi_panic ()
{
_session->midi_panic ();
}
void
BasicUI::toggle_click ()
{
bool state = !Config->get_clicking();
Config->set_clicking (state);
}
void
BasicUI::toggle_roll (bool roll_out_of_bounded_mode)
{
/* TO BE KEPT IN SYNC WITH ARDOUR_UI::toggle_roll() */
if (!_session) {
return;
}
if (_session->is_auditioning()) {
_session->cancel_audition ();
return;
}
if (_session->config.get_external_sync()) {
switch (TransportMasterManager::instance().current()->type()) {
case Engine:
break;
default:
/* transport controlled by the master */
return;
}
}
bool rolling = transport_rolling();
if (rolling) {
if (roll_out_of_bounded_mode) {
/* drop out of loop/range playback but leave transport rolling */
if (_session->get_play_loop()) {
if (_session->actively_recording()) {
/* actually stop transport because
otherwise the captured data will make
no sense.
*/
_session->request_play_loop (false, true);
} else {
_session->request_play_loop (false, false);
}
} else if (_session->get_play_range ()) {
_session->request_cancel_play_range ();
}
} else {
_session->request_stop (true, true);
}
} else { /* not rolling */
if (_session->get_play_loop() && Config->get_loop_is_mode()) {
_session->request_locate (_session->locations()->auto_loop_location()->start(), MustRoll);
} else {
_session->request_roll (TRS_UI);
}
}
}
void
BasicUI::stop_forget ()
{
_session->request_stop (true, true);
}
void BasicUI::mark_in () { access_action("Common/start-range-from-playhead"); } void BasicUI::mark_in () { access_action("Common/start-range-from-playhead"); }
void BasicUI::mark_out () { access_action("Common/finish-range-from-playhead"); } void BasicUI::mark_out () { access_action("Common/finish-range-from-playhead"); }
@ -708,62 +145,3 @@ void BasicUI::scroll_up_1_track() { access_action("Editor/step-tracks-up"); }
void BasicUI::scroll_dn_1_track() { access_action("Editor/step-tracks-down"); } void BasicUI::scroll_dn_1_track() { access_action("Editor/step-tracks-down"); }
void BasicUI::scroll_up_1_page() { access_action("Editor/scroll-tracks-up"); } void BasicUI::scroll_up_1_page() { access_action("Editor/scroll-tracks-up"); }
void BasicUI::scroll_dn_1_page() { access_action("Editor/scroll-tracks-down"); } void BasicUI::scroll_dn_1_page() { access_action("Editor/scroll-tracks-down"); }
bool
BasicUI::locating ()
{
return _session->locate_pending();
}
bool
BasicUI::locked ()
{
return _session->transport_locked ();
}
void
BasicUI::timecode_time (samplepos_t where, Timecode::Time& timecode)
{
_session->timecode_time (where, *((Timecode::Time *) &timecode));
}
void
BasicUI::cancel_all_solo ()
{
if (_session) {
_session->cancel_all_solo ();
}
}
struct SortLocationsByPosition {
bool operator() (Location* a, Location* b) {
return a->start() < b->start();
}
};
void
BasicUI::goto_nth_marker (int n)
{
if (!_session) {
return;
}
const Locations::LocationList& l (_session->locations()->list());
Locations::LocationList ordered;
ordered = l;
SortLocationsByPosition cmp;
ordered.sort (cmp);
for (Locations::LocationList::iterator i = ordered.begin(); n >= 0 && i != ordered.end(); ++i) {
if ((*i)->is_mark() && !(*i)->is_hidden() && !(*i)->is_session_range()) {
if (n == 0) {
_session->request_locate ((*i)->start());
break;
}
--n;
}
}
}

View file

@ -25,6 +25,7 @@
#include "ardour/presentation_info.h" #include "ardour/presentation_info.h"
#include "ardour/types.h" #include "ardour/types.h"
#include "control_protocol/session_controller.h"
#include "control_protocol/visibility.h" #include "control_protocol/visibility.h"
#include "pbd/signals.h" #include "pbd/signals.h"
#include "temporal/time.h" #include "temporal/time.h"
@ -41,75 +42,37 @@ class LIBCONTROLCP_API BasicUI {
BasicUI (Session&); BasicUI (Session&);
virtual ~BasicUI (); virtual ~BasicUI ();
void add_marker (const std::string& = std::string());
void remove_marker_at_playhead ();
void register_thread (std::string name); void register_thread (std::string name);
/* transport control */ /* Access to GUI actions */
void access_action (std::string action_path);
void loop_toggle ();
void loop_location (samplepos_t start, samplepos_t end);
void access_action ( std::string action_path );
static PBD::Signal2<void,std::string,std::string> AccessAction; static PBD::Signal2<void,std::string,std::string> AccessAction;
void goto_zero ();
void goto_start (bool and_roll = false);
void goto_end ();
void button_varispeed (bool fwd);
void rewind ();
void ffwd ();
void transport_stop ();
void transport_play (bool jump_back = false);
void set_transport_speed (double speed);
double get_transport_speed () const; /* Undo/Redo */
double transport_rolling () const;
void jump_by_seconds (double sec, LocateTransportDisposition ltd = RollIfAppropriate);
void jump_by_bars (double bars, LocateTransportDisposition ltd = RollIfAppropriate);
void jump_by_beats (double beats, LocateTransportDisposition ltd = RollIfAppropriate);
samplepos_t transport_sample ();
void locate (samplepos_t sample, LocateTransportDisposition ltd);
void locate (samplepos_t sample, bool);
bool locating ();
bool locked ();
void save_state ();
void prev_marker ();
void next_marker ();
void undo (); void undo ();
void redo (); void redo ();
void toggle_punch_in ();
void toggle_punch_out (); /* Convenience methods that fire actions */
void mark_in(); void mark_in();
void mark_out(); void mark_out();
void toggle_click();
void midi_panic();
void toggle_monitor_mute();
void toggle_monitor_dim();
void toggle_monitor_mono();
void cancel_all_solo ();
void quick_snapshot_stay (); void quick_snapshot_stay ();
void quick_snapshot_switch (); void quick_snapshot_switch ();
void toggle_roll(bool roll_out_of_bounded_mode=true); //this provides the same operation as the "spacebar", it's a lot smarter than "play".
void stop_forget();
void set_punch_range(); void set_punch_range();
void set_loop_range(); void set_loop_range();
void set_session_range(); void set_session_range();
void set_record_enable (bool yn); /* Editor Visibility
bool get_record_enabled ();
We need to explicitly bake in the "arguments" here, because GUI actions
don't have arguments.
*/
//editor visibility stuff (why do we have to make explicit numbers here? because "gui actions" don't accept args
void fit_1_track(); void fit_1_track();
void fit_2_tracks(); void fit_2_tracks();
void fit_4_tracks(); void fit_4_tracks();
@ -133,15 +96,7 @@ class LIBCONTROLCP_API BasicUI {
void scroll_up_1_page(); void scroll_up_1_page();
void scroll_dn_1_page(); void scroll_dn_1_page();
void rec_enable_toggle (); /* Button state */
void toggle_all_rec_enables ();
void all_tracks_rec_in ();
void all_tracks_rec_out ();
void goto_nth_marker (int n);
void timecode_time (samplepos_t where, Timecode::Time&);
bool stop_button_onoff() const; bool stop_button_onoff() const;
bool play_button_onoff() const; bool play_button_onoff() const;
@ -149,8 +104,11 @@ class LIBCONTROLCP_API BasicUI {
bool rewind_button_onoff() const; bool rewind_button_onoff() const;
bool loop_button_onoff() const; bool loop_button_onoff() const;
SessionController& controller() { return _controller; }
protected: protected:
Session* _session; Session* _session;
SessionController _controller;
}; };
} // namespace ARDOUR } // namespace ARDOUR

View file

@ -0,0 +1,141 @@
/*
* Copyright (C) 2006-2021 David Robillard <d@drobilla.net>
* Copyright (C) 2007-2017 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2010 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2015 Robin Gareus <robin@gareus.org>
* Copyright (C) 2016 Ben Loftis <ben@harrisonconsoles.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __ardour_session_controller_h__
#define __ardour_session_controller_h__
#include "ardour/types.h"
#include "control_protocol/visibility.h"
#include "temporal/time.h"
#include <cstdint>
#include <string>
namespace ARDOUR {
class Session;
/** A controller for a session used by UIs and control surfaces.
*
* This implements operations that manipulate a session which are common to any
* kind of UI. Application logic that isn't specific to any particular UI
* should go here and be reused, so UIs do things consistently and correctly.
*
* This only interacts with Session (and the objects it contains) directly, not
* with any UI facilities like actions or event loops.
*/
class LIBCONTROLCP_API SessionController
{
public:
SessionController (Session* s)
: _session (s)
{}
/* Transport Control */
void loop_toggle ();
void loop_location (samplepos_t start, samplepos_t end);
void button_varispeed (bool fwd);
void rewind ();
void ffwd ();
void transport_stop ();
void transport_play (bool jump_back = false);
void set_transport_speed (double speed);
void toggle_roll (bool roll_out_of_bounded_mode = true);
void stop_forget ();
double get_transport_speed () const;
bool transport_rolling () const;
samplepos_t transport_sample () const;
/* Markers */
void add_marker (const std::string& = std::string ());
void remove_marker_at_playhead ();
/* Locating */
void goto_zero ();
void goto_start (bool and_roll = false);
void goto_end ();
void goto_nth_marker (int n);
void jump_by_seconds (double sec,
LocateTransportDisposition ltd = RollIfAppropriate);
void jump_by_bars (double bars,
LocateTransportDisposition ltd = RollIfAppropriate);
void jump_by_beats (double beats,
LocateTransportDisposition ltd = RollIfAppropriate);
void locate (samplepos_t sample, LocateTransportDisposition ltd);
void locate (samplepos_t sample, bool);
void prev_marker ();
void next_marker ();
bool locating () const;
bool locked () const;
/* State */
void save_state ();
/* Monitoring */
void toggle_click ();
void midi_panic ();
void toggle_monitor_mute ();
void toggle_monitor_dim ();
void toggle_monitor_mono ();
void cancel_all_solo ();
/* Recording */
void toggle_punch_in ();
void toggle_punch_out ();
void set_record_enable (bool yn);
void rec_enable_toggle ();
void toggle_all_rec_enables ();
void all_tracks_rec_in ();
void all_tracks_rec_out ();
bool get_record_enabled () const;
/* Time */
void timecode_time (samplepos_t where, Timecode::Time&);
private:
Session* _session;
};
} // namespace ARDOUR
#endif /* __ardour_session_controller_h__ */

View file

@ -0,0 +1,685 @@
/*
* Copyright (C) 2006-2021 David Robillard <d@drobilla.net>
* Copyright (C) 2006-2018 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2009-2010 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2015 Robin Gareus <robin@gareus.org>
* Copyright (C) 2016-2017 Ben Loftis <ben@harrisonconsoles.com>
* Copyright (C) 2017-2019 Johannes Mueller <github@johannes-mueller.org>
* Copyright (C) 2017 Len Ovens <len@ovenwerks.net>
* Copyright (C) 2017 Tim Mayberry <mojofunk@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "control_protocol/session_controller.h"
#include "ardour/location.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
#include "ardour/transport_master_manager.h"
#include "ardour/utils.h"
#include "pbd/i18n.h"
#include "pbd/memento_command.h"
using namespace ARDOUR;
/* Transport Control */
void
SessionController::loop_toggle ()
{
if (!_session) {
return;
}
Location* looploc = _session->locations ()->auto_loop_location ();
if (!looploc) {
return;
}
if (_session->get_play_loop ()) {
/* looping enabled, our job is to disable it */
_session->request_play_loop (false);
} else {
/* looping not enabled, our job is to enable it.
loop-is-NOT-mode: this action always starts the transport rolling.
loop-IS-mode: this action simply sets the loop play mechanism,
but does not start transport.
*/
if (Config->get_loop_is_mode ()) {
_session->request_play_loop (true, false);
} else {
_session->request_play_loop (true, true);
}
}
// show the loop markers
looploc->set_hidden (false, this);
}
void
SessionController::loop_location (samplepos_t start, samplepos_t end)
{
Location* const tll = _session->locations ()->auto_loop_location ();
if (!tll) {
Location* loc = new Location (
*_session, start, end, _ ("Loop"), Location::IsAutoLoop);
_session->locations ()->add (loc, true);
_session->set_auto_loop_location (loc);
} else {
tll->set_hidden (false, this);
tll->set (start, end);
}
}
void
SessionController::button_varispeed (bool fwd)
{
// incrementally increase speed by semitones
// (keypress auto-repeat is 100ms)
const float maxspeed = Config->get_shuttle_max_speed ();
float semitone_ratio = exp2f (1.0f / 12.0f);
const float octave_down = pow (1.0 / semitone_ratio, 12.0);
float transport_speed = get_transport_speed ();
float speed;
if (Config->get_rewind_ffwd_like_tape_decks ()) {
if (fwd) {
if (transport_speed <= 0) {
_session->request_transport_speed (1.0, false);
_session->request_roll (TRS_UI);
return;
}
} else {
if (transport_speed >= 0) {
_session->request_transport_speed (-1.0, false);
_session->request_roll (TRS_UI);
return;
}
}
} else {
if (fabs (transport_speed) <= 0.1) {
/* close to zero, maybe flip direction */
if (fwd) {
if (transport_speed <= 0) {
_session->request_transport_speed (1.0, false);
_session->request_roll (TRS_UI);
}
} else {
if (transport_speed >= 0) {
_session->request_transport_speed (-1.0, false);
_session->request_roll (TRS_UI);
}
}
/* either we've just started, or we're moving as slowly as we
* ever should
*/
return;
}
if (fwd) {
if (transport_speed < 0.f) {
if (fabs (transport_speed) < octave_down) {
/* we need to move the speed back towards zero */
semitone_ratio = powf (1.f / semitone_ratio, 4.f);
} else {
semitone_ratio = 1.f / semitone_ratio;
}
} else {
if (fabs (transport_speed) < octave_down) {
/* moving very slowly, use 4 semitone steps */
semitone_ratio = powf (semitone_ratio, 4.f);
}
}
} else {
if (transport_speed > 0.f) {
/* we need to move the speed back towards zero */
if (transport_speed < octave_down) {
semitone_ratio = powf (1.f / semitone_ratio, 4.f);
} else {
semitone_ratio = 1.f / semitone_ratio;
}
} else {
if (fabs (transport_speed) < octave_down) {
/* moving very slowly, use 4 semitone steps */
semitone_ratio = powf (semitone_ratio, 4.f);
}
}
}
}
speed = semitone_ratio * transport_speed;
speed = std::max (-maxspeed, std::min (maxspeed, speed));
_session->request_transport_speed (speed, false);
_session->request_roll (TRS_UI);
}
void
SessionController::rewind ()
{
button_varispeed (false);
}
void
SessionController::ffwd ()
{
button_varispeed (true);
}
void
SessionController::transport_stop ()
{
_session->request_stop ();
}
void
SessionController::transport_play (bool from_last_start)
{
/* ::toggle_roll() is smarter and preferred */
if (!_session) {
return;
}
if (_session->is_auditioning ()) {
return;
}
bool rolling = transport_rolling ();
if (_session->get_play_loop ()) {
/* If loop playback is not a mode, then we should cancel
it when this action is requested. If it is a mode
we just leave it in place.
*/
if (!Config->get_loop_is_mode ()) {
/* XXX it is not possible to just leave seamless loop and keep
playing at present (nov 4th 2009)
*/
if (rolling) {
/* stop loop playback but keep rolling */
_session->request_play_loop (false, false);
}
}
} else if (_session->get_play_range ()) {
/* stop playing a range if we currently are */
_session->request_play_range (0, true);
}
if (rolling) {
_session->request_transport_speed (1.0, false, TRS_UI);
} else {
_session->request_roll ();
}
}
void
SessionController::set_transport_speed (double speed)
{
_session->request_transport_speed (speed);
}
void
SessionController::toggle_roll (bool roll_out_of_bounded_mode)
{
/* TO BE KEPT IN SYNC WITH ARDOUR_UI::toggle_roll() */
if (!_session) {
return;
}
if (_session->is_auditioning ()) {
_session->cancel_audition ();
return;
}
if (_session->config.get_external_sync ()) {
switch (TransportMasterManager::instance ().current ()->type ()) {
case Engine:
break;
default:
/* transport controlled by the master */
return;
}
}
bool rolling = transport_rolling ();
if (rolling) {
if (roll_out_of_bounded_mode) {
/* drop out of loop/range playback but leave transport rolling */
if (_session->get_play_loop ()) {
if (_session->actively_recording ()) {
/* actually stop transport because
otherwise the captured data will make
no sense.
*/
_session->request_play_loop (false, true);
} else {
_session->request_play_loop (false, false);
}
} else if (_session->get_play_range ()) {
_session->request_cancel_play_range ();
}
} else {
_session->request_stop (true, true);
}
} else { /* not rolling */
if (_session->get_play_loop () && Config->get_loop_is_mode ()) {
_session->request_locate (
_session->locations ()->auto_loop_location ()->start (),
MustRoll);
} else {
_session->request_roll (TRS_UI);
}
}
}
void
SessionController::stop_forget ()
{
_session->request_stop (true, true);
}
double
SessionController::get_transport_speed () const
{
return _session->actual_speed ();
}
bool
SessionController::transport_rolling () const
{
return !_session->transport_stopped_or_stopping ();
}
samplepos_t
SessionController::transport_sample () const
{
return _session->transport_sample ();
}
/* Markers */
void
SessionController::add_marker (const std::string& markername)
{
const samplepos_t where = _session->audible_sample ();
Location* location =
new Location (*_session, where, where, markername, Location::IsMark);
_session->begin_reversible_command (_ ("add marker"));
XMLNode& before = _session->locations ()->get_state ();
_session->locations ()->add (location, true);
XMLNode& after = _session->locations ()->get_state ();
_session->add_command (new MementoCommand<Locations> (
*(_session->locations ()), &before, &after));
_session->commit_reversible_command ();
}
void
SessionController::remove_marker_at_playhead ()
{
if (_session) {
// set up for undo
XMLNode& before = _session->locations ()->get_state ();
bool removed = false;
// find location(s) at this time
Locations::LocationList locs;
_session->locations ()->find_all_between (_session->audible_sample (),
_session->audible_sample () +
1,
locs,
Location::Flags (0));
for (Locations::LocationList::iterator i = locs.begin ();
i != locs.end ();
++i) {
if ((*i)->is_mark ()) {
_session->locations ()->remove (*i);
removed = true;
}
}
// store undo
if (removed) {
_session->begin_reversible_command (_ ("remove marker"));
XMLNode& after = _session->locations ()->get_state ();
_session->add_command (new MementoCommand<Locations> (
*(_session->locations ()), &before, &after));
_session->commit_reversible_command ();
}
}
}
/* Locating */
void
SessionController::goto_zero ()
{
_session->request_locate (0);
}
void
SessionController::goto_start (bool and_roll)
{
_session->goto_start (and_roll);
}
void
SessionController::goto_end ()
{
_session->goto_end ();
}
struct SortLocationsByPosition {
bool operator() (Location* a, Location* b)
{
return a->start () < b->start ();
}
};
void
SessionController::goto_nth_marker (int n)
{
if (!_session) {
return;
}
const Locations::LocationList& l (_session->locations ()->list ());
Locations::LocationList ordered;
ordered = l;
SortLocationsByPosition cmp;
ordered.sort (cmp);
for (Locations::LocationList::iterator i = ordered.begin ();
n >= 0 && i != ordered.end ();
++i) {
if ((*i)->is_mark () && !(*i)->is_hidden () &&
!(*i)->is_session_range ()) {
if (n == 0) {
_session->request_locate ((*i)->start ());
break;
}
--n;
}
}
}
void
SessionController::jump_by_seconds (double secs, LocateTransportDisposition ltd)
{
samplepos_t current = _session->transport_sample ();
double s = (double)current / (double)_session->nominal_sample_rate ();
s += secs;
if (s < 0) {
s = 0;
}
s = s * _session->nominal_sample_rate ();
_session->request_locate (floor (s), ltd);
}
void
SessionController::jump_by_bars (double bars, LocateTransportDisposition ltd)
{
TempoMap& tmap (_session->tempo_map ());
Timecode::BBT_Time bbt (tmap.bbt_at_sample (_session->transport_sample ()));
bars += bbt.bars;
if (bars < 0) {
bars = 0;
}
AnyTime any;
any.type = AnyTime::BBT;
any.bbt.bars = bars;
_session->request_locate (_session->convert_to_samples (any), ltd);
}
void
SessionController::jump_by_beats (double beats, LocateTransportDisposition ltd)
{
TempoMap& tmap (_session->tempo_map ());
double qn_goal =
tmap.quarter_note_at_sample (_session->transport_sample ()) + beats;
if (qn_goal < 0.0) {
qn_goal = 0.0;
}
_session->request_locate (tmap.sample_at_quarter_note (qn_goal), ltd);
}
void
SessionController::locate (samplepos_t where, LocateTransportDisposition ltd)
{
_session->request_locate (where, ltd);
}
void
SessionController::locate (samplepos_t where, bool roll)
{
_session->request_locate (where, roll ? MustRoll : RollIfAppropriate);
}
void
SessionController::prev_marker ()
{
samplepos_t pos =
_session->locations ()->first_mark_before (_session->transport_sample ());
if (pos >= 0) {
_session->request_locate (pos);
} else {
_session->goto_start ();
}
}
void
SessionController::next_marker ()
{
samplepos_t pos =
_session->locations ()->first_mark_after (_session->transport_sample ());
if (pos >= 0) {
_session->request_locate (pos);
} else {
_session->goto_end ();
}
}
bool
SessionController::locating () const
{
return _session->locate_pending ();
}
bool
SessionController::locked () const
{
return _session->transport_locked ();
}
/* State */
void
SessionController::save_state ()
{
_session->save_state ("");
}
/* Monitoring */
void
SessionController::toggle_click ()
{
bool state = !Config->get_clicking ();
Config->set_clicking (state);
}
void
SessionController::midi_panic ()
{
_session->midi_panic ();
}
void
SessionController::toggle_monitor_mute ()
{
if (_session->monitor_out ()) {
boost::shared_ptr<MonitorProcessor> mon =
_session->monitor_out ()->monitor_control ();
if (mon->cut_all ()) {
mon->set_cut_all (false);
} else {
mon->set_cut_all (true);
}
}
}
void
SessionController::toggle_monitor_dim ()
{
if (_session->monitor_out ()) {
boost::shared_ptr<MonitorProcessor> mon =
_session->monitor_out ()->monitor_control ();
if (mon->dim_all ()) {
mon->set_dim_all (false);
} else {
mon->set_dim_all (true);
}
}
}
void
SessionController::toggle_monitor_mono ()
{
if (_session->monitor_out ()) {
boost::shared_ptr<MonitorProcessor> mon =
_session->monitor_out ()->monitor_control ();
if (mon->mono ()) {
mon->set_mono (false);
} else {
mon->set_mono (true);
}
}
}
void
SessionController::cancel_all_solo ()
{
if (_session) {
_session->cancel_all_solo ();
}
}
/* Recording */
void
SessionController::toggle_punch_in ()
{
_session->config.set_punch_in (!_session->config.get_punch_in ());
}
void
SessionController::toggle_punch_out ()
{
_session->config.set_punch_out (!_session->config.get_punch_out ());
}
void
SessionController::set_record_enable (bool yn)
{
if (yn) {
_session->maybe_enable_record ();
} else {
_session->disable_record (false, true);
}
}
void
SessionController::rec_enable_toggle ()
{
switch (_session->record_status ()) {
case (RecordState)Disabled:
if (_session->ntracks () > 0) {
_session->maybe_enable_record ();
}
break;
case (RecordState)Recording:
case (RecordState)Enabled:
_session->disable_record (false, true);
}
}
void
SessionController::toggle_all_rec_enables ()
{
if (_session->get_record_enabled ()) {
// _session->record_disenable_all ();
} else {
// _session->record_enable_all ();
}
}
void
SessionController::all_tracks_rec_in ()
{
_session->set_all_tracks_record_enabled (true);
}
void
SessionController::all_tracks_rec_out ()
{
_session->set_all_tracks_record_enabled (false);
}
bool
SessionController::get_record_enabled () const
{
return _session->get_record_enabled ();
}
/* Time */
void
SessionController::timecode_time (samplepos_t where, Timecode::Time& timecode)
{
_session->timecode_time (where, *((Timecode::Time*)&timecode));
}

View file

@ -10,6 +10,7 @@ controlcp_sources = [
'basic_ui.cc', 'basic_ui.cc',
'control_protocol.cc', 'control_protocol.cc',
'midi_byte_array.cc', 'midi_byte_array.cc',
'session_controller.cc',
] ]
def options(opt): def options(opt):

View file

@ -159,30 +159,30 @@ FaderPort::FaderPort (Session& s)
get_button (FP_Touch).set_action (boost::bind (&FaderPort::off, this), false, LongPress); get_button (FP_Touch).set_action (boost::bind (&FaderPort::off, this), false, LongPress);
get_button (FP_Off).set_action (boost::bind (&FaderPort::off, this), true); get_button (FP_Off).set_action (boost::bind (&FaderPort::off, this), true);
get_button (Play).set_action (boost::bind (&BasicUI::transport_play, this, true), true); get_button (Play).set_action (boost::bind (&SessionController::transport_play, _controller, true), true);
get_button (RecEnable).set_action (boost::bind (&BasicUI::rec_enable_toggle, this), true); get_button (RecEnable).set_action (boost::bind (&SessionController::rec_enable_toggle, _controller), true);
/* Stop is a modifier, so we have to use its own button state to get /* Stop is a modifier, so we have to use its own button state to get
the default action (since StopDown will be set when looking for the the default action (since StopDown will be set when looking for the
action to invoke. action to invoke.
*/ */
get_button (Stop).set_action (boost::bind (&BasicUI::transport_stop, this), true, StopDown); get_button (Stop).set_action (boost::bind (&SessionController::transport_stop, _controller), true, StopDown);
get_button (Ffwd).set_action (boost::bind (&BasicUI::ffwd, this), true); get_button (Ffwd).set_action (boost::bind (&SessionController::ffwd, _controller), true);
/* See comments about Stop above .. */ /* See comments about Stop above .. */
get_button (Rewind).set_action (boost::bind (&BasicUI::rewind, this), true, RewindDown); get_button (Rewind).set_action (boost::bind (&SessionController::rewind, _controller), true, RewindDown);
get_button (Rewind).set_action (boost::bind (&BasicUI::goto_zero, this), true, ButtonState (RewindDown|StopDown)); get_button (Rewind).set_action (boost::bind (&SessionController::goto_zero, _controller), true, ButtonState (RewindDown|StopDown));
get_button (Rewind).set_action (boost::bind (&BasicUI::goto_start, this, false), true, ButtonState (RewindDown|ShiftDown)); get_button (Rewind).set_action (boost::bind (&SessionController::goto_start, _controller, false), true, ButtonState (RewindDown|ShiftDown));
get_button (Ffwd).set_action (boost::bind (&BasicUI::ffwd, this), true); get_button (Ffwd).set_action (boost::bind (&SessionController::ffwd, _controller), true);
get_button (Ffwd).set_action (boost::bind (&BasicUI::goto_end, this), true, ShiftDown); get_button (Ffwd).set_action (boost::bind (&SessionController::goto_end, _controller), true, ShiftDown);
get_button (Punch).set_action (boost::bind (&FaderPort::punch, this), true); get_button (Punch).set_action (boost::bind (&FaderPort::punch, this), true);
get_button (Loop).set_action (boost::bind (&BasicUI::loop_toggle, this), true); get_button (Loop).set_action (boost::bind (&SessionController::loop_toggle, _controller), true);
get_button (Loop).set_action (boost::bind (&BasicUI::add_marker, this, string()), true, ShiftDown); get_button (Loop).set_action (boost::bind (&SessionController::add_marker, _controller, string()), true, ShiftDown);
get_button (Punch).set_action (boost::bind (&BasicUI::prev_marker, this), true, ShiftDown); get_button (Punch).set_action (boost::bind (&SessionController::prev_marker, _controller), true, ShiftDown);
get_button (User).set_action (boost::bind (&BasicUI::next_marker, this), true, ShiftDown); get_button (User).set_action (boost::bind (&SessionController::next_marker, _controller), true, ShiftDown);
get_button (Mute).set_action (boost::bind (&FaderPort::mute, this), true); get_button (Mute).set_action (boost::bind (&FaderPort::mute, this), true);
get_button (Solo).set_action (boost::bind (&FaderPort::solo, this), true); get_button (Solo).set_action (boost::bind (&FaderPort::solo, this), true);
@ -686,7 +686,7 @@ FaderPort::map_transport_state ()
{ {
get_button (Loop).set_led_state (_output_port, _session->get_play_loop()); get_button (Loop).set_led_state (_output_port, _session->get_play_loop());
float ts = get_transport_speed(); float ts = _controller.get_transport_speed();
if (ts == 0) { if (ts == 0) {
stop_blinking (Play); stop_blinking (Play);

View file

@ -135,22 +135,22 @@ FaderPort8::setup_actions ()
void void
FaderPort8::button_play () FaderPort8::button_play ()
{ {
if (transport_rolling ()) { if (_controller.transport_rolling ()) {
if (get_transport_speed() != 1.0) { if (_controller.get_transport_speed() != 1.0) {
_session->request_roll (TRS_UI); _session->request_roll (TRS_UI);
} else { } else {
transport_stop (); _controller.transport_stop ();
} }
} else { } else {
transport_play (); _controller.transport_play ();
} }
} }
void void
FaderPort8::button_stop () FaderPort8::button_stop ()
{ {
if (transport_rolling ()) { if (_controller.transport_rolling ()) {
transport_stop (); _controller.transport_stop ();
} else { } else {
AccessAction ("Transport", "GotoStart"); AccessAction ("Transport", "GotoStart");
} }
@ -159,13 +159,13 @@ FaderPort8::button_stop ()
void void
FaderPort8::button_record () FaderPort8::button_record ()
{ {
set_record_enable (!get_record_enabled ()); _controller.set_record_enable (!_controller.get_record_enabled ());
} }
void void
FaderPort8::button_loop () FaderPort8::button_loop ()
{ {
loop_toggle (); _controller.loop_toggle ();
} }
void void
@ -313,7 +313,7 @@ FaderPort8::button_varispeed (bool ffw)
return; return;
} }
BasicUI::button_varispeed (ffw); _controller.button_varispeed (ffw);
} }
#ifdef FP8_MUTESOLO_UNDO #ifdef FP8_MUTESOLO_UNDO
@ -336,7 +336,7 @@ FaderPort8::button_solo_clear ()
_solo_state.push_back (boost::weak_ptr<AutomationControl>(sc)); _solo_state.push_back (boost::weak_ptr<AutomationControl>(sc));
} }
} }
cancel_all_solo (); // AccessAction ("Main", "cancel-solo"); _controller.cancel_all_solo (); // AccessAction ("Main", "cancel-solo");
} else { } else {
/* restore solo */ /* restore solo */
boost::shared_ptr<ControlList> cl (new ControlList); boost::shared_ptr<ControlList> cl (new ControlList);
@ -384,7 +384,7 @@ FaderPort8::button_mute_clear ()
void void
FaderPort8::button_arm_all () FaderPort8::button_arm_all ()
{ {
BasicUI::all_tracks_rec_in (); _controller.all_tracks_rec_in ();
} }
/* access generic action */ /* access generic action */
@ -513,9 +513,9 @@ FaderPort8::button_prev_next (bool next)
break; break;
case NavMarker: case NavMarker:
if (next) { if (next) {
next_marker (); _controller.next_marker ();
} else { } else {
prev_marker (); _controller.prev_marker ();
} }
break; break;
} }
@ -576,7 +576,7 @@ FaderPort8::button_encoder ()
} }
_session->locations()->next_available_name (markername,"mark"); _session->locations()->next_available_name (markername,"mark");
add_marker (markername); _controller.add_marker (markername);
} }
break; break;
} }

View file

@ -125,11 +125,11 @@ FaderPort8::notify_parameter_changed (std::string param)
void void
FaderPort8::notify_transport_state_changed () FaderPort8::notify_transport_state_changed ()
{ {
_ctrls.button (FP8Controls::BtnPlay).set_active (get_transport_speed()==1.0); _ctrls.button (FP8Controls::BtnPlay).set_active (_controller.get_transport_speed()==1.0);
_ctrls.button (FP8Controls::BtnStop).set_active (get_transport_speed()==0.0); _ctrls.button (FP8Controls::BtnStop).set_active (_controller.get_transport_speed()==0.0);
/* set rewind/fastforward lights */ /* set rewind/fastforward lights */
const float ts = get_transport_speed(); const float ts = _controller.get_transport_speed();
FP8ButtonInterface& b_rew = _ctrls.button (FP8Controls::BtnRewind); FP8ButtonInterface& b_rew = _ctrls.button (FP8Controls::BtnRewind);
FP8ButtonInterface& b_ffw = _ctrls.button (FP8Controls::BtnFastForward); FP8ButtonInterface& b_ffw = _ctrls.button (FP8Controls::BtnFastForward);

View file

@ -119,17 +119,17 @@ MIDIFunction::execute ()
break; break;
case TransportStop: case TransportStop:
_ui->transport_stop (); _ui->controller().transport_stop ();
DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_stop\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_stop\n");
break; break;
case TransportRoll: case TransportRoll:
_ui->transport_play (); _ui->controller().transport_play ();
DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_play\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: transport_play\n");
break; break;
case TransportStart: case TransportStart:
_ui->goto_start (); _ui->controller().goto_start ();
DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_start\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_start\n");
break; break;
@ -139,27 +139,27 @@ MIDIFunction::execute ()
break; break;
case TransportEnd: case TransportEnd:
_ui->goto_end (); _ui->controller().goto_end ();
DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_end\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: goto_end\n");
break; break;
case TransportLoopToggle: case TransportLoopToggle:
_ui->loop_toggle (); _ui->controller().loop_toggle ();
DEBUG_TRACE (DEBUG::GenericMidi, "Function: loop_toggle\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: loop_toggle\n");
break; break;
case TransportRecordToggle: case TransportRecordToggle:
_ui->rec_enable_toggle (); _ui->controller().rec_enable_toggle ();
DEBUG_TRACE (DEBUG::GenericMidi, "Function: toggle_record_enable\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: toggle_record_enable\n");
break; break;
case TransportRecordEnable: case TransportRecordEnable:
_ui->set_record_enable (true); _ui->controller().set_record_enable (true);
DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = true\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = true\n");
break; break;
case TransportRecordDisable: case TransportRecordDisable:
_ui->set_record_enable (false); _ui->controller().set_record_enable (false);
DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = false\n"); DEBUG_TRACE (DEBUG::GenericMidi, "Function: set_record_enable = false\n");
break; break;
@ -168,7 +168,7 @@ MIDIFunction::execute ()
uint32_t rid; uint32_t rid;
sscanf (_argument.c_str(), "%d", &rid); sscanf (_argument.c_str(), "%d", &rid);
// XX fix me ... need to get stripable, not RID // XX fix me ... need to get stripable, not RID
//_ui->toggle_selection (rid, ARDOUR::PresentationInfo::Flag (ARDOUR::PresentationInfo::Route|ARDOUR::PresentationInfo::VCA)); //_ui->controller().toggle_selection (rid, ARDOUR::PresentationInfo::Flag (ARDOUR::PresentationInfo::Route|ARDOUR::PresentationInfo::VCA));
DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Function: SetRouteSelection = %1\n", rid)); DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Function: SetRouteSelection = %1\n", rid));
} }
break; break;

View file

@ -1030,7 +1030,7 @@ LaunchControlXL::button_solo()
void void
LaunchControlXL::button_solo_long_press() LaunchControlXL::button_solo_long_press()
{ {
cancel_all_solo(); _controller.cancel_all_solo();
} }
void void

View file

@ -73,9 +73,9 @@ void JogWheel::jog_event (float delta)
break; break;
default: default:
if (delta > 0) { if (delta > 0) {
_mcp.button_varispeed (true); _mcp.controller ().button_varispeed (true);
} else if (delta < 0) { } else if (delta < 0) {
_mcp.button_varispeed (false); _mcp.controller ().button_varispeed (false);
} }
break; break;
} }

View file

@ -370,7 +370,7 @@ LedState
MackieControlProtocol::undo_press (Button&) MackieControlProtocol::undo_press (Button&)
{ {
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
redo(); redo ();
} else { } else {
undo (); undo ();
} }
@ -387,7 +387,7 @@ LedState
MackieControlProtocol::drop_press (Button &) MackieControlProtocol::drop_press (Button &)
{ {
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
toggle_punch_in(); _controller.toggle_punch_in();
return none; return none;
} else { } else {
access_action ("Common/start-range-from-playhead"); access_action ("Common/start-range-from-playhead");
@ -407,7 +407,7 @@ MackieControlProtocol::save_press (Button &)
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
quick_snapshot_switch(); quick_snapshot_switch();
} else { } else {
save_state (); _controller.save_state ();
} }
return none; return none;
@ -490,7 +490,7 @@ MackieControlProtocol::marker_release (Button &)
} }
_session->locations()->next_available_name (markername,"mark"); _session->locations()->next_available_name (markername,"mark");
add_marker (markername); _controller.add_marker (markername);
return off; return off;
} }
@ -502,7 +502,7 @@ MackieControlProtocol::marker_release (Button &)
LedState LedState
MackieControlProtocol::stop_press (Button &) MackieControlProtocol::stop_press (Button &)
{ {
transport_stop (); _controller.transport_stop ();
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
_session->midi_panic(); _session->midi_panic();
@ -524,7 +524,7 @@ MackieControlProtocol::play_press (Button &)
again, jump back to where we started last time again, jump back to where we started last time
*/ */
transport_play (get_transport_speed() == 1.0); _controller.transport_play (_controller.get_transport_speed() == 1.0);
return none; return none;
} }
@ -537,7 +537,7 @@ MackieControlProtocol::play_release (Button &)
LedState LedState
MackieControlProtocol::record_press (Button &) MackieControlProtocol::record_press (Button &)
{ {
rec_enable_toggle (); _controller.rec_enable_toggle ();
return none; return none;
} }
@ -551,13 +551,13 @@ LedState
MackieControlProtocol::rewind_press (Button &) MackieControlProtocol::rewind_press (Button &)
{ {
if (modifier_state() & MODIFIER_MARKER) { if (modifier_state() & MODIFIER_MARKER) {
prev_marker (); _controller.prev_marker ();
} else if (modifier_state() & MODIFIER_NUDGE) { } else if (modifier_state() & MODIFIER_NUDGE) {
access_action ("Common/nudge-playhead-backward"); access_action ("Common/nudge-playhead-backward");
} else if (main_modifier_state() & MODIFIER_SHIFT) { } else if (main_modifier_state() & MODIFIER_SHIFT) {
goto_start (); _controller.goto_start ();
} else { } else {
rewind (); _controller.rewind ();
} }
return none; return none;
} }
@ -572,13 +572,13 @@ LedState
MackieControlProtocol::ffwd_press (Button &) MackieControlProtocol::ffwd_press (Button &)
{ {
if (modifier_state() & MODIFIER_MARKER) { if (modifier_state() & MODIFIER_MARKER) {
next_marker (); _controller.next_marker ();
} else if (modifier_state() & MODIFIER_NUDGE) { } else if (modifier_state() & MODIFIER_NUDGE) {
access_action ("Common/nudge-playhead-forward"); access_action ("Common/nudge-playhead-forward");
} else if (main_modifier_state() & MODIFIER_SHIFT) { } else if (main_modifier_state() & MODIFIER_SHIFT) {
goto_end(); _controller.goto_end();
} else { } else {
ffwd (); _controller.ffwd ();
} }
return none; return none;
} }
@ -597,7 +597,7 @@ MackieControlProtocol::loop_press (Button &)
return off; return off;
} else { } else {
bool was_on = _session->get_play_loop(); bool was_on = _session->get_play_loop();
loop_toggle (); _controller.loop_toggle ();
return was_on ? off : on; return was_on ? off : on;
} }
} }
@ -837,7 +837,7 @@ MackieControlProtocol::cancel_release (Button &)
LedState LedState
MackieControlProtocol::user_a_press (Button &) MackieControlProtocol::user_a_press (Button &)
{ {
transport_play (get_transport_speed() == 1.0); _controller.transport_play (_controller.get_transport_speed() == 1.0);
return off; return off;
} }
LedState LedState
@ -848,7 +848,7 @@ MackieControlProtocol::user_a_release (Button &)
LedState LedState
MackieControlProtocol::user_b_press (Button &) MackieControlProtocol::user_b_press (Button &)
{ {
transport_stop(); _controller.transport_stop();
return off; return off;
} }
LedState LedState
@ -920,7 +920,7 @@ MackieControlProtocol::clearsolo_press (Mackie::Button&)
return none; return none;
} }
cancel_all_solo (); _controller.cancel_all_solo ();
return none; return none;
} }
@ -1109,7 +1109,7 @@ Mackie::LedState
MackieControlProtocol::replace_press (Mackie::Button&) MackieControlProtocol::replace_press (Mackie::Button&)
{ {
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
toggle_punch_out(); _controller.toggle_punch_out();
return none; return none;
} else { } else {
access_action ("Common/finish-range-from-playhead"); access_action ("Common/finish-range-from-playhead");

View file

@ -1231,7 +1231,7 @@ Strip::notify_metering_state_changed()
return; return;
} }
bool transport_is_rolling = (_surface->mcp().get_transport_speed () != 0.0f); bool transport_is_rolling = (_surface->mcp().controller().get_transport_speed () != 0.0f);
bool metering_active = _surface->mcp().metering_active (); bool metering_active = _surface->mcp().metering_active ();
if ((_transport_is_rolling == transport_is_rolling) && (_metering_active == metering_active)) { if ((_transport_is_rolling == transport_is_rolling) && (_metering_active == metering_active)) {

View file

@ -127,7 +127,7 @@ Maschine2::notify_record_state_changed ()
void void
Maschine2::notify_transport_state_changed () Maschine2::notify_transport_state_changed ()
{ {
if (transport_rolling ()) { if (_controller.transport_rolling ()) {
_ctrl->button (M2Contols::Play)->set_color (COLOR_WHITE); _ctrl->button (M2Contols::Play)->set_color (COLOR_WHITE);
} else { } else {
_ctrl->button (M2Contols::Play)->set_color (0); _ctrl->button (M2Contols::Play)->set_color (0);
@ -198,23 +198,23 @@ Maschine2::notify_history_changed ()
void void
Maschine2::button_play () Maschine2::button_play ()
{ {
if (transport_rolling ()) { if (_controller.transport_rolling ()) {
transport_stop (); _controller.transport_stop ();
} else { } else {
transport_play (); _controller.transport_play ();
} }
} }
void void
Maschine2::button_record () Maschine2::button_record ()
{ {
set_record_enable (!get_record_enabled ()); _controller.set_record_enable (!_controller.get_record_enabled ());
} }
void void
Maschine2::button_loop () Maschine2::button_loop ()
{ {
loop_toggle (); _controller.loop_toggle ();
} }
void void
@ -226,7 +226,7 @@ Maschine2::button_metronom ()
void void
Maschine2::button_rewind () Maschine2::button_rewind ()
{ {
goto_start (transport_rolling ()); _controller.goto_start (_controller.transport_rolling ());
} }
void void

View file

@ -1279,7 +1279,7 @@ OSC::osc_toggle_roll (bool ret2strt)
return 0; return 0;
} }
bool rolling = transport_rolling(); bool rolling = _controller.transport_rolling();
if (rolling) { if (rolling) {
_session->request_stop (ret2strt, true); _session->request_stop (ret2strt, true);
@ -2915,7 +2915,7 @@ void
OSC::transport_speed (lo_message msg) OSC::transport_speed (lo_message msg)
{ {
check_surface (msg); check_surface (msg);
double ts = get_transport_speed(); double ts = _controller.get_transport_speed();
lo_message reply = lo_message_new (); lo_message reply = lo_message_new ();
lo_message_add_double (reply, ts); lo_message_add_double (reply, ts);
@ -2994,7 +2994,7 @@ OSC::jog (float delta, lo_message msg)
{ {
case 0: case 0:
if (delta) { if (delta) {
jump_by_seconds (delta / 5); _controller.jump_by_seconds (delta / 5);
} }
break; break;
case 1: case 1:
@ -3009,17 +3009,17 @@ OSC::jog (float delta, lo_message msg)
break; break;
case 3: case 3:
if (delta) { if (delta) {
double speed = get_transport_speed (); double speed = _controller.get_transport_speed ();
set_transport_speed (speed + (delta / 8.1)); _controller.set_transport_speed (speed + (delta / 8.1));
} else { } else {
set_transport_speed (0); _controller.set_transport_speed (0);
} }
break; break;
case 4: case 4:
if (delta > 0) { if (delta > 0) {
next_marker (); _controller.next_marker ();
} else if (delta < 0) { } else if (delta < 0) {
prev_marker (); _controller.prev_marker ();
} }
break; break;
case 5: case 5:
@ -3055,8 +3055,8 @@ int
OSC::jog_mode (float mode, lo_message msg) OSC::jog_mode (float mode, lo_message msg)
{ {
OSCSurface *s = get_surface(get_address (msg)); OSCSurface *s = get_surface(get_address (msg));
if (get_transport_speed () != 1.0) { if (_controller.get_transport_speed () != 1.0) {
set_transport_speed (0); _controller.set_transport_speed (0);
} }
s->jogmode = (uint32_t) mode; s->jogmode = (uint32_t) mode;
s->global_obs->jog_mode (mode); s->global_obs->jog_mode (mode);

View file

@ -344,7 +344,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
void record_enabled (lo_message msg); void record_enabled (lo_message msg);
void add_marker_name(const std::string &markername) { void add_marker_name(const std::string &markername) {
add_marker(markername); _controller.add_marker(markername);
} }
// cue // cue
@ -416,38 +416,50 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
return 0; \ return 0; \
} }
PATH_CALLBACK(add_marker); #define PATH_CONTROLLER_CALLBACK(name) \
PATH_CALLBACK(loop_toggle); static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { \
PATH_CALLBACK(goto_start); return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, msg); \
PATH_CALLBACK(goto_end); } \
PATH_CALLBACK(rewind); int cb_ ## name (const char *path, const char *types, lo_arg ** argv, int argc, lo_message msg) { \
PATH_CALLBACK(ffwd); OSC_DEBUG; \
PATH_CALLBACK(transport_stop); check_surface (msg); \
PATH_CALLBACK(transport_play); if (argc > 0 && !strcmp (types, "f") && argv[0]->f != 1.0) { return 0; } \
PATH_CALLBACK(save_state); _controller.name (); \
PATH_CALLBACK(prev_marker); return 0; \
PATH_CALLBACK(next_marker); }
PATH_CONTROLLER_CALLBACK(add_marker);
PATH_CONTROLLER_CALLBACK(loop_toggle);
PATH_CONTROLLER_CALLBACK(goto_start);
PATH_CONTROLLER_CALLBACK(goto_end);
PATH_CONTROLLER_CALLBACK(rewind);
PATH_CONTROLLER_CALLBACK(ffwd);
PATH_CONTROLLER_CALLBACK(transport_stop);
PATH_CONTROLLER_CALLBACK(transport_play);
PATH_CONTROLLER_CALLBACK(save_state);
PATH_CONTROLLER_CALLBACK(prev_marker);
PATH_CONTROLLER_CALLBACK(next_marker);
PATH_CALLBACK(undo); PATH_CALLBACK(undo);
PATH_CALLBACK(redo); PATH_CALLBACK(redo);
PATH_CALLBACK(toggle_punch_in); PATH_CONTROLLER_CALLBACK(toggle_punch_in);
PATH_CALLBACK(toggle_punch_out); PATH_CONTROLLER_CALLBACK(toggle_punch_out);
PATH_CALLBACK(rec_enable_toggle); PATH_CONTROLLER_CALLBACK(rec_enable_toggle);
PATH_CALLBACK(toggle_all_rec_enables); PATH_CONTROLLER_CALLBACK(toggle_all_rec_enables);
PATH_CALLBACK(all_tracks_rec_in); PATH_CONTROLLER_CALLBACK(all_tracks_rec_in);
PATH_CALLBACK(all_tracks_rec_out); PATH_CONTROLLER_CALLBACK(all_tracks_rec_out);
PATH_CALLBACK(cancel_all_solos); PATH_CALLBACK(cancel_all_solos);
PATH_CALLBACK(remove_marker_at_playhead); PATH_CONTROLLER_CALLBACK(remove_marker_at_playhead);
PATH_CALLBACK(mark_in); PATH_CALLBACK(mark_in);
PATH_CALLBACK(mark_out); PATH_CALLBACK(mark_out);
PATH_CALLBACK(toggle_click); PATH_CONTROLLER_CALLBACK(toggle_click);
PATH_CALLBACK(midi_panic); PATH_CONTROLLER_CALLBACK(midi_panic);
PATH_CALLBACK(stop_forget); PATH_CONTROLLER_CALLBACK(stop_forget);
PATH_CALLBACK(set_punch_range); PATH_CALLBACK(set_punch_range);
PATH_CALLBACK(set_loop_range); PATH_CALLBACK(set_loop_range);
PATH_CALLBACK(set_session_range); PATH_CALLBACK(set_session_range);
PATH_CALLBACK(toggle_monitor_mute); PATH_CONTROLLER_CALLBACK(toggle_monitor_mute);
PATH_CALLBACK(toggle_monitor_dim); PATH_CONTROLLER_CALLBACK(toggle_monitor_dim);
PATH_CALLBACK(toggle_monitor_mono); PATH_CONTROLLER_CALLBACK(toggle_monitor_mono);
PATH_CALLBACK(quick_snapshot_stay); PATH_CALLBACK(quick_snapshot_stay);
PATH_CALLBACK(quick_snapshot_switch); PATH_CALLBACK(quick_snapshot_switch);
PATH_CALLBACK(fit_1_track); PATH_CALLBACK(fit_1_track);
@ -484,12 +496,25 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
return 0; \ return 0; \
} }
PATH_CALLBACK1(set_transport_speed,f,); #define PATH_CONTROLLER_CALLBACK1(name,type,optional) \
static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { \
return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, msg); \
} \
int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg) { \
OSC_DEBUG; \
check_surface (msg); \
if (argc > 0) { \
_controller.name (optional argv[0]->type); \
} \
return 0; \
}
PATH_CONTROLLER_CALLBACK1(set_transport_speed,f,);
PATH_CALLBACK1(add_marker_name,s,&); PATH_CALLBACK1(add_marker_name,s,&);
PATH_CALLBACK1(access_action,s,&); PATH_CALLBACK1(access_action,s,&);
PATH_CALLBACK1(jump_by_bars,f,); PATH_CONTROLLER_CALLBACK1(jump_by_bars,f,);
PATH_CALLBACK1(jump_by_seconds,f,); PATH_CONTROLLER_CALLBACK1(jump_by_seconds,f,);
PATH_CALLBACK1(click_level,f,); PATH_CALLBACK1(click_level,f,);
#define PATH_CALLBACK1_MSG(name,arg1type) \ #define PATH_CALLBACK1_MSG(name,arg1type) \
@ -559,6 +584,19 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
return 0; \ return 0; \
} }
#define PATH_CONTROLLER_CALLBACK2(name,arg1type,arg2type) \
static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { \
return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, msg); \
} \
int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg) { \
OSC_DEBUG; \
check_surface (msg); \
if (argc > 1) { \
_controller.name (argv[0]->arg1type, argv[1]->arg2type); \
} \
return 0; \
}
#define PATH_CALLBACK2_MSG(name,arg1type,arg2type) \ #define PATH_CALLBACK2_MSG(name,arg1type,arg2type) \
static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { \ static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { \
return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, msg); \ return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, msg); \
@ -615,8 +653,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
PATH_CALLBACK2_MSG(sel_eq_q,i,f); PATH_CALLBACK2_MSG(sel_eq_q,i,f);
PATH_CALLBACK2_MSG(sel_eq_shape,i,f); PATH_CALLBACK2_MSG(sel_eq_shape,i,f);
PATH_CALLBACK2(locate,i,i); PATH_CONTROLLER_CALLBACK2(locate,i,i);
PATH_CALLBACK2(loop_location,i,i); PATH_CONTROLLER_CALLBACK2(loop_location,i,i);
PATH_CALLBACK3(route_set_send_gain_dB,i,i,f); PATH_CALLBACK3(route_set_send_gain_dB,i,i,f);
PATH_CALLBACK3(route_set_send_fader,i,i,f); PATH_CALLBACK3(route_set_send_fader,i,i,f);
PATH_CALLBACK3(route_set_send_enable,i,i,f); PATH_CALLBACK3(route_set_send_enable,i,i,f);

View file

@ -360,7 +360,7 @@ Push2::button_play ()
} }
if (_modifier_state & ModShift) { if (_modifier_state & ModShift) {
goto_start (_session->transport_rolling()); _controller.goto_start (_session->transport_rolling());
return; return;
} }
@ -376,16 +376,16 @@ Push2::button_play ()
} }
if (_session->transport_rolling ()) { if (_session->transport_rolling ()) {
transport_stop (); _controller.transport_stop ();
} else { } else {
transport_play (); _controller.transport_play ();
} }
} }
void void
Push2::button_recenable () Push2::button_recenable ()
{ {
rec_enable_toggle (); _controller.rec_enable_toggle ();
} }
void void
@ -427,19 +427,19 @@ Push2::button_left ()
void void
Push2::button_repeat () Push2::button_repeat ()
{ {
loop_toggle (); _controller.loop_toggle ();
} }
void void
Push2::button_metronome () Push2::button_metronome ()
{ {
toggle_click (); _controller.toggle_click ();
} }
void void
Push2::button_solo_long_press () Push2::button_solo_long_press ()
{ {
cancel_all_solo (); _controller.cancel_all_solo ();
} }
void void
@ -527,56 +527,56 @@ void
Push2::button_fwd32t () Push2::button_fwd32t ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (0+n); _controller.goto_nth_marker (0+n);
} }
void void
Push2::button_fwd32 () Push2::button_fwd32 ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (1+n); _controller.goto_nth_marker (1+n);
} }
void void
Push2::button_fwd16t () Push2::button_fwd16t ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (2+n); _controller.goto_nth_marker (2+n);
} }
void void
Push2::button_fwd16 () Push2::button_fwd16 ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (3+n); _controller.goto_nth_marker (3+n);
} }
void void
Push2::button_fwd8t () Push2::button_fwd8t ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (4+n); _controller.goto_nth_marker (4+n);
} }
void void
Push2::button_fwd8 () Push2::button_fwd8 ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (5+n); _controller.goto_nth_marker (5+n);
} }
void void
Push2::button_fwd4t () Push2::button_fwd4t ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (6+n); _controller.goto_nth_marker (6+n);
} }
void void
Push2::button_fwd4 () Push2::button_fwd4 ()
{ {
const int n = (_modifier_state & ModShift) ? 8 : 0; const int n = (_modifier_state & ModShift) ? 8 : 0;
goto_nth_marker (7+n); _controller.goto_nth_marker (7+n);
} }
void void

View file

@ -764,7 +764,7 @@ Push2::handle_midi_note_on_message (MIDI::Parser& parser, MIDI::EventTwoBytes* e
/* touch strip */ /* touch strip */
case 12: case 12:
if (ev->velocity < 64) { if (ev->velocity < 64) {
transport_stop (); _controller.transport_stop ();
} }
break; break;
} }

View file

@ -380,7 +380,7 @@ US2400Protocol::save_press (Button &)
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
quick_snapshot_switch(); quick_snapshot_switch();
} else { } else {
save_state (); _controller.save_state ();
} }
return none; return none;
@ -463,7 +463,7 @@ US2400Protocol::marker_release (Button &)
} }
_session->locations()->next_available_name (markername,"mark"); _session->locations()->next_available_name (markername,"mark");
add_marker (markername); _controller.add_marker (markername);
return off; return off;
} }
@ -475,7 +475,7 @@ US2400Protocol::marker_release (Button &)
LedState LedState
US2400Protocol::stop_press (Button &) US2400Protocol::stop_press (Button &)
{ {
transport_stop (); _controller.transport_stop ();
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
_session->midi_panic(); _session->midi_panic();
@ -497,7 +497,7 @@ US2400Protocol::play_press (Button &)
again, jump back to where we started last time again, jump back to where we started last time
*/ */
transport_play (get_transport_speed() == 1.0); _controller.transport_play (_controller.get_transport_speed() == 1.0);
return none; return none;
} }
@ -510,7 +510,7 @@ US2400Protocol::play_release (Button &)
LedState LedState
US2400Protocol::record_press (Button &) US2400Protocol::record_press (Button &)
{ {
rec_enable_toggle (); _controller.rec_enable_toggle ();
return none; return none;
} }
@ -524,13 +524,13 @@ LedState
US2400Protocol::rewind_press (Button &) US2400Protocol::rewind_press (Button &)
{ {
if (modifier_state() & MODIFIER_MARKER) { if (modifier_state() & MODIFIER_MARKER) {
prev_marker (); _controller.prev_marker ();
} else if ( (_modifier_state & MODIFIER_DROP) == MODIFIER_DROP) { } else if ( (_modifier_state & MODIFIER_DROP) == MODIFIER_DROP) {
access_action ("Common/start-range-from-playhead"); access_action ("Common/start-range-from-playhead");
} else if (main_modifier_state() & MODIFIER_SHIFT) { } else if (main_modifier_state() & MODIFIER_SHIFT) {
goto_start (); _controller.goto_start ();
} else { } else {
rewind (); _controller.rewind ();
} }
return none; return none;
} }
@ -545,13 +545,13 @@ LedState
US2400Protocol::ffwd_press (Button &) US2400Protocol::ffwd_press (Button &)
{ {
if (modifier_state() & MODIFIER_MARKER) { if (modifier_state() & MODIFIER_MARKER) {
next_marker (); _controller.next_marker ();
} else if ( (_modifier_state & MODIFIER_DROP) == MODIFIER_DROP) { } else if ( (_modifier_state & MODIFIER_DROP) == MODIFIER_DROP) {
access_action ("Common/finish-range-from-playhead"); access_action ("Common/finish-range-from-playhead");
} else if (main_modifier_state() & MODIFIER_SHIFT) { } else if (main_modifier_state() & MODIFIER_SHIFT) {
goto_end(); _controller.goto_end();
} else { } else {
ffwd (); _controller.ffwd ();
} }
return none; return none;
} }
@ -570,7 +570,7 @@ US2400Protocol::loop_press (Button &)
return off; return off;
} else { } else {
bool was_on = _session->get_play_loop(); bool was_on = _session->get_play_loop();
loop_toggle (); _controller.loop_toggle ();
return was_on ? off : on; return was_on ? off : on;
} }
} }
@ -821,7 +821,7 @@ US2400Protocol::cancel_release (Button &)
LedState LedState
US2400Protocol::user_a_press (Button &) US2400Protocol::user_a_press (Button &)
{ {
transport_play (get_transport_speed() == 1.0); _controller.transport_play (_controller.get_transport_speed() == 1.0);
return off; return off;
} }
LedState LedState
@ -832,7 +832,7 @@ US2400Protocol::user_a_release (Button &)
LedState LedState
US2400Protocol::user_b_press (Button &) US2400Protocol::user_b_press (Button &)
{ {
transport_stop(); _controller.transport_stop();
return off; return off;
} }
LedState LedState
@ -897,7 +897,7 @@ US2400Protocol::clearsolo_press (US2400::Button&)
{ {
// clears all solos and listens (pfl/afl) // clears all solos and listens (pfl/afl)
if (main_modifier_state() & MODIFIER_OPTION) { if (main_modifier_state() & MODIFIER_OPTION) {
cancel_all_solo (); _controller.cancel_all_solo ();
} }
return none; return none;
@ -1082,7 +1082,7 @@ US2400::LedState
US2400Protocol::replace_press (US2400::Button&) US2400Protocol::replace_press (US2400::Button&)
{ {
if (main_modifier_state() == MODIFIER_SHIFT) { if (main_modifier_state() == MODIFIER_SHIFT) {
toggle_punch_out(); _controller.toggle_punch_out();
return none; return none;
} else { } else {
access_action ("Common/finish-range-from-playhead"); access_action ("Common/finish-range-from-playhead");

View file

@ -993,7 +993,7 @@ Strip::notify_metering_state_changed()
return; return;
} }
bool transport_is_rolling = (_surface->mcp().get_transport_speed () != 0.0f); bool transport_is_rolling = (_surface->mcp().controller ().get_transport_speed () != 0.0f);
bool metering_active = _surface->mcp().metering_active (); bool metering_active = _surface->mcp().metering_active ();
if ((_transport_is_rolling == transport_is_rolling) && (_metering_active == metering_active)) { if ((_transport_is_rolling == transport_is_rolling) && (_metering_active == metering_active)) {

View file

@ -50,7 +50,7 @@ ArdourTransport::time () const
bool bool
ArdourTransport::roll () const ArdourTransport::roll () const
{ {
return basic_ui ().transport_rolling (); return basic_ui ().controller ().transport_rolling ();
} }
void void
@ -58,7 +58,7 @@ ArdourTransport::set_roll (bool value)
{ {
if ((value && !roll ()) || (!value && roll ())) { if ((value && !roll ()) || (!value && roll ())) {
// this call is equivalent to hitting the spacebar // this call is equivalent to hitting the spacebar
basic_ui ().toggle_roll (false); basic_ui ().controller ().toggle_roll (false);
} }
} }
@ -72,6 +72,6 @@ void
ArdourTransport::set_record (bool value) ArdourTransport::set_record (bool value)
{ {
if ((value && !record ()) || (!value && record ())) { if ((value && !record ()) || (!value && record ())) {
basic_ui ().rec_enable_toggle (); basic_ui ().controller ().rec_enable_toggle ();
} }
} }

View file

@ -299,7 +299,7 @@ WiimoteControlProtocol::update_led_state ()
} }
// enable LED1 if Ardour is playing // enable LED1 if Ardour is playing
if (transport_rolling ()) { if (_controller.transport_rolling ()) {
DEBUG_TRACE (DEBUG::WiimoteControl, "WiimoteControlProtocol::update_led_state playing, activate LED1\n"); DEBUG_TRACE (DEBUG::WiimoteControl, "WiimoteControlProtocol::update_led_state playing, activate LED1\n");
state |= CWIID_LED1_ON; state |= CWIID_LED1_ON;
} }
@ -365,12 +365,12 @@ WiimoteControlProtocol::wiimote_callback (int mesg_count, union cwiid_mesg mesg[
// B + up = move playhead to next marker // B + up = move playhead to next marker
if (b & CWIID_BTN_UP) { if (b & CWIID_BTN_UP) {
next_marker (); _controller.next_marker ();
} }
// B + down = move playhead to prev marker // B + down = move playhead to prev marker
if (b & CWIID_BTN_DOWN) { if (b & CWIID_BTN_DOWN) {
prev_marker (); _controller.prev_marker ();
} }
// B + Home = add marker at playhead // B + Home = add marker at playhead
@ -400,7 +400,7 @@ WiimoteControlProtocol::wiimote_callback (int mesg_count, union cwiid_mesg mesg[
// 2 = enable recording in general // 2 = enable recording in general
if (b & CWIID_BTN_2) { if (b & CWIID_BTN_2) {
rec_enable_toggle (); _controller.rec_enable_toggle ();
} }
// left = move playhead back a bit // left = move playhead back a bit