initial work on livetrax all-mono, direct outs and send-to-(master/monitor?)

This commit is contained in:
Paul Davis 2024-03-25 10:31:57 -06:00
parent 3aaa066652
commit 3f81b73f36
5 changed files with 123 additions and 46 deletions

View file

@ -99,6 +99,7 @@ class MonitorControl;
class TriggerBox; class TriggerBox;
class SurroundReturn; class SurroundReturn;
class SurroundSend; class SurroundSend;
class Send;
class LIBARDOUR_API Route : public Stripable, class LIBARDOUR_API Route : public Stripable,
public GraphNode, public GraphNode,
@ -695,6 +696,7 @@ protected:
std::shared_ptr<PeakMeter> _meter; std::shared_ptr<PeakMeter> _meter;
std::shared_ptr<PolarityProcessor> _polarity; std::shared_ptr<PolarityProcessor> _polarity;
std::shared_ptr<TriggerBox> _triggerbox; std::shared_ptr<TriggerBox> _triggerbox;
std::shared_ptr<InternalSend> _master_send;
bool _volume_applies_to_output; bool _volume_applies_to_output;

View file

@ -1804,6 +1804,7 @@ private:
MidiPortFlags exclude = MidiPortFlags (0)); MidiPortFlags exclude = MidiPortFlags (0));
void auto_connect (const AutoConnectRequest&); void auto_connect (const AutoConnectRequest&);
void livetrax_auto_connect (std::shared_ptr<Route>);
void queue_latency_recompute (); void queue_latency_recompute ();
/* SessionEventManager interface */ /* SessionEventManager interface */
@ -1984,6 +1985,7 @@ private:
bool find_route_name (std::string const &, uint32_t& id, std::string& name, bool); bool find_route_name (std::string const &, uint32_t& id, std::string& name, bool);
void count_existing_track_channels (ChanCount& in, ChanCount& out); void count_existing_track_channels (ChanCount& in, ChanCount& out);
void auto_connect_route (std::shared_ptr<Route>, bool, bool, const ChanCount&, const ChanCount&, const ChanCount& io = ChanCount(), const ChanCount& oo = ChanCount()); void auto_connect_route (std::shared_ptr<Route>, bool, bool, const ChanCount&, const ChanCount&, const ChanCount& io = ChanCount(), const ChanCount& oo = ChanCount());
void livetrax_auto_connect_route (std::shared_ptr<Route>);
void midi_output_change_handler (IOChange change, void* /*src*/, std::weak_ptr<Route> midi_track); void midi_output_change_handler (IOChange change, void* /*src*/, std::weak_ptr<Route> midi_track);
/* track numbering */ /* track numbering */

View file

@ -316,6 +316,11 @@ Route::init ()
panner_shell()->select_panner_by_uri ("http://ardour.org/plugin/panner_balance"); panner_shell()->select_panner_by_uri ("http://ardour.org/plugin/panner_balance");
} }
if (Profile->get_livetrax() && is_track()) {
_master_send.reset (new InternalSend (_session, _pannable, _mute_master, std::dynamic_pointer_cast<Route> (shared_from_this()), std::shared_ptr<Route>(), Delivery::Aux, false));
_master_send->set_display_to_user (false);
}
/* now set up processor chain and invisible processors */ /* now set up processor chain and invisible processors */
{ {
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
@ -1847,7 +1852,8 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
if ((*p)->can_support_io_configuration(in, out)) { if ((*p)->can_support_io_configuration(in, out)) {
if (std::dynamic_pointer_cast<Delivery> (*p) if (!Profile->get_livetrax()
&& std::dynamic_pointer_cast<Delivery> (*p)
&& std::dynamic_pointer_cast<Delivery> (*p)->role() == Delivery::Main && std::dynamic_pointer_cast<Delivery> (*p)->role() == Delivery::Main
&& !is_auditioner() && !is_auditioner()
&& (is_monitor() || _strict_io || Profile->get_mixbus ())) { && (is_monitor() || _strict_io || Profile->get_mixbus ())) {
@ -2522,11 +2528,19 @@ Route::customize_plugin_insert (std::shared_ptr<Processor> proc, uint32_t count,
} }
bool bool
Route::set_strict_io (const bool enable) Route::set_strict_io (bool enable)
{ {
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
if (_strict_io != enable) { if (Profile->get_livetrax()) {
/* cannot be disabled, and is set to true by default */
// enable = true;
}
if (_strict_io == enable) {
return true;
}
_strict_io = enable; _strict_io = enable;
Glib::Threads::RWLock::ReaderLock lm (_processor_lock); Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) { for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
@ -2556,7 +2570,7 @@ Route::set_strict_io (const bool enable)
processors_changed (RouteProcessorChange (RouteProcessorChange::CustomPinChange, false)); /* EMIT SIGNAL */ processors_changed (RouteProcessorChange (RouteProcessorChange::CustomPinChange, false)); /* EMIT SIGNAL */
_session.set_dirty (); _session.set_dirty ();
}
return true; return true;
} }
@ -5284,6 +5298,12 @@ Route::setup_invisible_processors ()
new_processors.push_back (_surround_send); new_processors.push_back (_surround_send);
} }
if (Profile->get_livetrax() && is_track()) {
assert (_master_send);
assert (!_master_send->display_to_user());
new_processors.push_back (_master_send);
}
/* MAIN OUTS */ /* MAIN OUTS */
assert (_main_outs); assert (_main_outs);

View file

@ -36,6 +36,7 @@
#include "ardour/io.h" #include "ardour/io.h"
#include "ardour/meter.h" #include "ardour/meter.h"
#include "ardour/panner_shell.h" #include "ardour/panner_shell.h"
#include "ardour/profile.h"
#include "ardour/send.h" #include "ardour/send.h"
#include "ardour/session.h" #include "ardour/session.h"
@ -72,9 +73,17 @@ Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot, bool ignore_b
return string (); return string ();
} }
switch (r) { switch (r) {
case Delivery::Aux: case Delivery::Aux:
if (Profile->get_livetrax()) {
/* The only type of aux send possible with livetrax */
return _("master");
} else {
return string_compose (_("aux %1"), (bitslot = s.next_aux_send_id ())); return string_compose (_("aux %1"), (bitslot = s.next_aux_send_id ()));
}
case Delivery::Listen: case Delivery::Listen:
bitslot = 0; /* unused */ bitslot = 0; /* unused */
return _("listen"); // no ports, no need for numbering return _("listen"); // no ports, no need for numbering
@ -551,6 +560,10 @@ Send::set_name (const string& new_name)
bool bool
Send::display_to_user () const Send::display_to_user () const
{ {
if (_role == Aux && Profile->get_livetrax()) {
return false;
}
/* we ignore Deliver::_display_to_user */ /* we ignore Deliver::_display_to_user */
if (_role == Listen || _role == Foldback) { if (_role == Listen || _role == Foldback) {

View file

@ -3021,6 +3021,8 @@ Session::new_audio_track (int input_channels, int output_channels, RouteGroup* r
goto failed; goto failed;
} }
std::cerr << "new track with " << output_channels << " channels\n";
if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) { if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
error << string_compose ( error << string_compose (
_("cannot configure %1 in/%2 out configuration for new audio track"), _("cannot configure %1 in/%2 out configuration for new audio track"),
@ -3524,6 +3526,8 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
{ {
PresentationInfo::ChangeSuspender cs; PresentationInfo::ChangeSuspender cs;
ensure_route_presentation_info_gap (order, new_routes.size()); ensure_route_presentation_info_gap (order, new_routes.size());
ensure_stripable_sort_order ();
reassign_track_numbers ();
for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x, ++added) { for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x, ++added) {
@ -3603,7 +3607,6 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
ARDOUR::GUIIdle (); ARDOUR::GUIIdle ();
} }
ensure_stripable_sort_order ();
} }
if (_monitor_out && !loading()) { if (_monitor_out && !loading()) {
@ -3622,8 +3625,6 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
r->enable_surround_send (); r->enable_surround_send ();
} }
} }
reassign_track_numbers ();
} }
void void
@ -4580,15 +4581,19 @@ Session::reassign_track_numbers ()
StateProtector sp (this); StateProtector sp (this);
for (RouteList::iterator i = r.begin(); i != r.end(); ++i) { for (auto & route : r) {
assert (!(*i)->is_auditioner()); assert (!route->is_auditioner());
if (std::dynamic_pointer_cast<Track> (*i)) { if (std::dynamic_pointer_cast<Track> (route)) {
(*i)->set_track_number(++tn); route->set_track_number(++tn);
} else if (!(*i)->is_main_bus ()) { } else if (!route->is_main_bus ()) {
(*i)->set_track_number(--bn); route->set_track_number(--bn);
} }
std::shared_ptr<TriggerBox> tb = (*i)->triggerbox(); if (Profile->get_livetrax() && !route->is_auditioner() && route->is_track()) {
livetrax_auto_connect_route (route);
}
std::shared_ptr<TriggerBox> tb = (route)->triggerbox();
if (tb) { if (tb) {
tb->set_order (trigger_order); tb->set_order (trigger_order);
trigger_order++; trigger_order++;
@ -4599,8 +4604,8 @@ Session::reassign_track_numbers ()
_track_number_decimals = decimals; _track_number_decimals = decimals;
if (decimals_changed && config.get_track_name_number ()) { if (decimals_changed && config.get_track_name_number ()) {
for (RouteList::iterator i = r.begin(); i != r.end(); ++i) { for (auto & route : r) {
std::shared_ptr<Track> t = std::dynamic_pointer_cast<Track> (*i); std::shared_ptr<Track> t = std::dynamic_pointer_cast<Track> (route);
if (t) { if (t) {
t->resync_take_name (); t->resync_take_name ();
} }
@ -7669,6 +7674,13 @@ Session::cut_copy_section (timepos_t const& start_, timepos_t const& end_, timep
commit_reversible_command (); commit_reversible_command ();
} }
void
Session::livetrax_auto_connect_route (std::shared_ptr<Route> route)
{
ChanCount ignored;
auto_connect_route (route, true, true, ignored, ignored, ignored, ignored);
}
void void
Session::auto_connect_route (std::shared_ptr<Route> route, Session::auto_connect_route (std::shared_ptr<Route> route,
bool connect_inputs, bool connect_inputs,
@ -7710,6 +7722,27 @@ Session::queue_latency_recompute ()
auto_connect_thread_wakeup (); auto_connect_thread_wakeup ();
} }
void
Session::livetrax_auto_connect (std::shared_ptr<Route> route)
{
vector<string> physinputs;
vector<string> physoutputs;
get_physical_ports (physinputs, physoutputs, DataType::AUDIO);
const vector<string>::size_type n = route->track_number() - 1;
route->input()->disconnect (this);
route->output()->disconnect (this);
route->input()->connect (route->input()->ports().port (DataType::AUDIO, 0), physinputs[n % physinputs.size()], this);
route->output()->connect (route->output()->ports().port (DataType::AUDIO, 0), physoutputs[n % physoutputs.size()], this);
DEBUG_TRACE (DEBUG::PortConnectAuto, string_compose ("livetrax auto connect %1 [%2] to %3 and %4\n", route->name(), route->track_number(),
physinputs[n % physinputs.size()],
physoutputs[n % physoutputs.size()]));
}
void void
Session::auto_connect (const AutoConnectRequest& ar) Session::auto_connect (const AutoConnectRequest& ar)
{ {
@ -7721,6 +7754,11 @@ Session::auto_connect (const AutoConnectRequest& ar)
return; return;
} }
if (Profile->get_livetrax() && !route->is_auditioner() && route->is_track()) {
livetrax_auto_connect (route);
return;
}
/* If both inputs and outputs are auto-connected to physical ports, /* If both inputs and outputs are auto-connected to physical ports,
* use the max of input and output offsets to ensure auto-connected * use the max of input and output offsets to ensure auto-connected
* port numbers always match up (e.g. the first audio input and the * port numbers always match up (e.g. the first audio input and the
@ -7750,7 +7788,6 @@ Session::auto_connect (const AutoConnectRequest& ar)
vector<string> physinputs; vector<string> physinputs;
vector<string> physoutputs; vector<string> physoutputs;
/* for connecting track inputs we only want MIDI ports marked /* for connecting track inputs we only want MIDI ports marked
* for "music". * for "music".
*/ */
@ -7775,6 +7812,8 @@ Session::auto_connect (const AutoConnectRequest& ar)
DEBUG_TRACE (DEBUG::PortConnectAuto, "Failed to auto-connect input."); DEBUG_TRACE (DEBUG::PortConnectAuto, "Failed to auto-connect input.");
break; break;
} }
DEBUG_TRACE (DEBUG::PortConnectAuto, string_compose ("autoconnected input %1/%2 [%4]to %3\n", route->name(), i, port, route->track_number()));
} }
} }
@ -7801,6 +7840,8 @@ Session::auto_connect (const AutoConnectRequest& ar)
DEBUG_TRACE (DEBUG::PortConnectAuto, "Failed to auto-connect output."); DEBUG_TRACE (DEBUG::PortConnectAuto, "Failed to auto-connect output.");
break; break;
} }
DEBUG_TRACE (DEBUG::PortConnectAuto, string_compose ("autoconnected output %1/%2 [%4]to %3\n", route->name(), i, port, route->track_number()));
} }
} }
} }
@ -8132,4 +8173,3 @@ Session::foreach_route (void (Route::*method)())
((r.get())->*method) (); ((r.get())->*method) ();
} }
} }