initial work on livetrax all-mono, direct outs and send-to-(master/monitor?)
This commit is contained in:
parent
3aaa066652
commit
3f81b73f36
|
@ -99,6 +99,7 @@ class MonitorControl;
|
|||
class TriggerBox;
|
||||
class SurroundReturn;
|
||||
class SurroundSend;
|
||||
class Send;
|
||||
|
||||
class LIBARDOUR_API Route : public Stripable,
|
||||
public GraphNode,
|
||||
|
@ -695,6 +696,7 @@ protected:
|
|||
std::shared_ptr<PeakMeter> _meter;
|
||||
std::shared_ptr<PolarityProcessor> _polarity;
|
||||
std::shared_ptr<TriggerBox> _triggerbox;
|
||||
std::shared_ptr<InternalSend> _master_send;
|
||||
|
||||
bool _volume_applies_to_output;
|
||||
|
||||
|
|
|
@ -1804,6 +1804,7 @@ private:
|
|||
MidiPortFlags exclude = MidiPortFlags (0));
|
||||
|
||||
void auto_connect (const AutoConnectRequest&);
|
||||
void livetrax_auto_connect (std::shared_ptr<Route>);
|
||||
void queue_latency_recompute ();
|
||||
|
||||
/* SessionEventManager interface */
|
||||
|
@ -1984,6 +1985,7 @@ private:
|
|||
bool find_route_name (std::string const &, uint32_t& id, std::string& name, bool);
|
||||
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 livetrax_auto_connect_route (std::shared_ptr<Route>);
|
||||
void midi_output_change_handler (IOChange change, void* /*src*/, std::weak_ptr<Route> midi_track);
|
||||
|
||||
/* track numbering */
|
||||
|
|
|
@ -316,6 +316,11 @@ Route::init ()
|
|||
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 */
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
|
||||
|
@ -1847,10 +1852,11 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
|
|||
|
||||
if ((*p)->can_support_io_configuration(in, out)) {
|
||||
|
||||
if (std::dynamic_pointer_cast<Delivery> (*p)
|
||||
&& std::dynamic_pointer_cast<Delivery> (*p)->role() == Delivery::Main
|
||||
&& !is_auditioner()
|
||||
&& (is_monitor() || _strict_io || Profile->get_mixbus ())) {
|
||||
if (!Profile->get_livetrax()
|
||||
&& std::dynamic_pointer_cast<Delivery> (*p)
|
||||
&& std::dynamic_pointer_cast<Delivery> (*p)->role() == Delivery::Main
|
||||
&& !is_auditioner()
|
||||
&& (is_monitor() || _strict_io || Profile->get_mixbus ())) {
|
||||
/* with strict I/O the panner + output are forced to
|
||||
* follow the last processor's output.
|
||||
*
|
||||
|
@ -2522,41 +2528,49 @@ Route::customize_plugin_insert (std::shared_ptr<Processor> proc, uint32_t count,
|
|||
}
|
||||
|
||||
bool
|
||||
Route::set_strict_io (const bool enable)
|
||||
Route::set_strict_io (bool enable)
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
|
||||
|
||||
if (_strict_io != enable) {
|
||||
_strict_io = enable;
|
||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
|
||||
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;
|
||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
|
||||
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
|
||||
std::shared_ptr<PluginInsert> pi;
|
||||
if ((pi = std::dynamic_pointer_cast<PluginInsert>(*p)) != 0) {
|
||||
pi->set_strict_io (_strict_io);
|
||||
}
|
||||
}
|
||||
|
||||
list<pair<ChanCount, ChanCount> > c = try_configure_processors_unlocked (n_inputs (), 0);
|
||||
|
||||
if (c.empty()) {
|
||||
// not possible
|
||||
_strict_io = !enable; // restore old value
|
||||
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
|
||||
std::shared_ptr<PluginInsert> pi;
|
||||
if ((pi = std::dynamic_pointer_cast<PluginInsert>(*p)) != 0) {
|
||||
pi->set_strict_io (_strict_io);
|
||||
}
|
||||
}
|
||||
|
||||
list<pair<ChanCount, ChanCount> > c = try_configure_processors_unlocked (n_inputs (), 0);
|
||||
|
||||
if (c.empty()) {
|
||||
// not possible
|
||||
_strict_io = !enable; // restore old value
|
||||
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
|
||||
std::shared_ptr<PluginInsert> pi;
|
||||
if ((pi = std::dynamic_pointer_cast<PluginInsert>(*p)) != 0) {
|
||||
pi->set_strict_io (_strict_io);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
lm.release ();
|
||||
|
||||
configure_processors (0);
|
||||
lx.release ();
|
||||
|
||||
processors_changed (RouteProcessorChange (RouteProcessorChange::CustomPinChange, false)); /* EMIT SIGNAL */
|
||||
_session.set_dirty ();
|
||||
return false;
|
||||
}
|
||||
lm.release ();
|
||||
|
||||
configure_processors (0);
|
||||
lx.release ();
|
||||
|
||||
processors_changed (RouteProcessorChange (RouteProcessorChange::CustomPinChange, false)); /* EMIT SIGNAL */
|
||||
_session.set_dirty ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5284,6 +5298,12 @@ Route::setup_invisible_processors ()
|
|||
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 */
|
||||
|
||||
assert (_main_outs);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "ardour/io.h"
|
||||
#include "ardour/meter.h"
|
||||
#include "ardour/panner_shell.h"
|
||||
#include "ardour/profile.h"
|
||||
#include "ardour/send.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 ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
switch (r) {
|
||||
case Delivery::Aux:
|
||||
return string_compose (_("aux %1"), (bitslot = s.next_aux_send_id ()));
|
||||
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 ()));
|
||||
}
|
||||
case Delivery::Listen:
|
||||
bitslot = 0; /* unused */
|
||||
return _("listen"); // no ports, no need for numbering
|
||||
|
@ -551,6 +560,10 @@ Send::set_name (const string& new_name)
|
|||
bool
|
||||
Send::display_to_user () const
|
||||
{
|
||||
if (_role == Aux && Profile->get_livetrax()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* we ignore Deliver::_display_to_user */
|
||||
|
||||
if (_role == Listen || _role == Foldback) {
|
||||
|
|
|
@ -3021,6 +3021,8 @@ Session::new_audio_track (int input_channels, int output_channels, RouteGroup* r
|
|||
goto failed;
|
||||
}
|
||||
|
||||
std::cerr << "new track with " << output_channels << " channels\n";
|
||||
|
||||
if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
|
||||
error << string_compose (
|
||||
_("cannot configure %1 in/%2 out configuration for new audio track"),
|
||||
|
@ -3104,7 +3106,7 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
|
|||
<< endmsg;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
|
||||
error << string_compose (_("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;
|
||||
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) {
|
||||
|
||||
|
@ -3603,7 +3607,6 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
|
|||
|
||||
ARDOUR::GUIIdle ();
|
||||
}
|
||||
ensure_stripable_sort_order ();
|
||||
}
|
||||
|
||||
if (_monitor_out && !loading()) {
|
||||
|
@ -3622,8 +3625,6 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
|
|||
r->enable_surround_send ();
|
||||
}
|
||||
}
|
||||
|
||||
reassign_track_numbers ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4580,15 +4581,19 @@ Session::reassign_track_numbers ()
|
|||
|
||||
StateProtector sp (this);
|
||||
|
||||
for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
|
||||
assert (!(*i)->is_auditioner());
|
||||
if (std::dynamic_pointer_cast<Track> (*i)) {
|
||||
(*i)->set_track_number(++tn);
|
||||
} else if (!(*i)->is_main_bus ()) {
|
||||
(*i)->set_track_number(--bn);
|
||||
for (auto & route : r) {
|
||||
assert (!route->is_auditioner());
|
||||
if (std::dynamic_pointer_cast<Track> (route)) {
|
||||
route->set_track_number(++tn);
|
||||
} else if (!route->is_main_bus ()) {
|
||||
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) {
|
||||
tb->set_order (trigger_order);
|
||||
trigger_order++;
|
||||
|
@ -4599,8 +4604,8 @@ Session::reassign_track_numbers ()
|
|||
_track_number_decimals = decimals;
|
||||
|
||||
if (decimals_changed && config.get_track_name_number ()) {
|
||||
for (RouteList::iterator i = r.begin(); i != r.end(); ++i) {
|
||||
std::shared_ptr<Track> t = std::dynamic_pointer_cast<Track> (*i);
|
||||
for (auto & route : r) {
|
||||
std::shared_ptr<Track> t = std::dynamic_pointer_cast<Track> (route);
|
||||
if (t) {
|
||||
t->resync_take_name ();
|
||||
}
|
||||
|
@ -6462,7 +6467,7 @@ Session::write_one_track (Track& track, samplepos_t start, samplepos_t end,
|
|||
|
||||
plist.add (Properties::whole_file, true);
|
||||
plist.add (Properties::length, len); //ToDo: in nutempo, if the Range is snapped to bbt, this should be in bbt (?)
|
||||
plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true)); // TODO: allow custom region-name when consolidating
|
||||
plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true)); // TODO: allow custom region-name when consolidating
|
||||
plist.add (Properties::tags, "(bounce)");
|
||||
|
||||
result = RegionFactory::create (srcs, plist, true);
|
||||
|
@ -7669,6 +7674,13 @@ Session::cut_copy_section (timepos_t const& start_, timepos_t const& end_, timep
|
|||
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
|
||||
Session::auto_connect_route (std::shared_ptr<Route> route,
|
||||
bool connect_inputs,
|
||||
|
@ -7710,6 +7722,27 @@ Session::queue_latency_recompute ()
|
|||
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
|
||||
Session::auto_connect (const AutoConnectRequest& ar)
|
||||
{
|
||||
|
@ -7721,6 +7754,11 @@ Session::auto_connect (const AutoConnectRequest& ar)
|
|||
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,
|
||||
* 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
|
||||
|
@ -7750,7 +7788,6 @@ Session::auto_connect (const AutoConnectRequest& ar)
|
|||
vector<string> physinputs;
|
||||
vector<string> physoutputs;
|
||||
|
||||
|
||||
/* for connecting track inputs we only want MIDI ports marked
|
||||
* for "music".
|
||||
*/
|
||||
|
@ -7775,6 +7812,8 @@ Session::auto_connect (const AutoConnectRequest& ar)
|
|||
DEBUG_TRACE (DEBUG::PortConnectAuto, "Failed to auto-connect input.");
|
||||
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.");
|
||||
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) ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue