13
0

Compare commits

...

11 Commits

Author SHA1 Message Date
5f0c2a4d32 Merge branch 'ardour' 2024-05-10 08:37:13 -06:00
41c68ffc19 ensure that the master send is directly before the main outs. 2024-05-10 08:37:09 -06:00
bf69e367ac revert inadvertently committed change made for debugging. 2024-05-10 08:37:09 -06:00
f9a76829f3 fix for metering of a MasterSend (internal send)
Metering for these sends should be effectively PostFader not Output,
and should not reflect the impact of solo & mute.
2024-05-10 08:37:09 -06:00
21f4dce2d9 for DEBUG::Processors, use display_name() not name()
This allows us to differentiate between different instances of the same
type of processor (e.g. Trim vs Fader, which are both of type Amp)
2024-05-10 08:37:09 -06:00
fce1f15a87 avoid timecnt_t exception when loading a region with an excessively long length
This is not a fix for whatever underlying problem causes this, but it does allow sessions to load
when the faulty region(s) are not in use
2024-05-10 08:36:06 -06:00
dcdcaf4b47 ensure that the master send is directly before the main outs. 2024-05-10 08:35:03 -06:00
b929e8a4e2 revert inadvertently committed change made for debugging. 2024-05-10 08:35:03 -06:00
de1a425704 fix for metering of a MasterSend (internal send)
Metering for these sends should be effectively PostFader not Output,
and should not reflect the impact of solo & mute.
2024-05-10 08:35:03 -06:00
edc03002eb for DEBUG::Processors, use display_name() not name()
This allows us to differentiate between different instances of the same
type of processor (e.g. Trim vs Fader, which are both of type Amp)
2024-05-10 08:35:03 -06:00
John Emmas
2e55f4452f As we've yet to implement user options, let's prefer AAF filenames rather than extracting an internal Comp name
This helps to avoid situations where 2 x unrelated AAF imports use the same name internally - and/or they give us meaningless session names like "Untitled.ardour"
2024-05-10 15:07:44 +01:00
4 changed files with 81 additions and 35 deletions

View File

@ -466,7 +466,7 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
}
/* extract or set session name */
if (aafi->compositionName && aafi->compositionName[0] != 0x00) {
if (/* Temporary - in the absence of user-options, don't rely on extracted session names which can be meaningless... aafi->compositionName && aafi->compositionName[0] != */ 0x00) {
string compositionName = string (aafi->compositionName);
snapshot = laaf_util_clean_filename (&compositionName[0]);
} else {

View File

@ -240,29 +240,34 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
_panshell->run (bufs, mixbufs, start_sample + latency, end_sample + latency, nframes);
}
/* non-audio data will not have been copied by the panner, do it now
* if there are more buffers available than send buffers, ignore them,
* if there are less, copy the last as IO::copy_to_output does. */
/* No need to handle non-audio if this is the MasterSend */
for (DataType::iterator t = DataType::begin (); t != DataType::end (); ++t) {
if (*t != DataType::AUDIO) {
BufferSet::iterator o = mixbufs.begin (*t);
BufferSet::iterator i = bufs.begin (*t);
if (role() != MasterSend) {
while (i != bufs.end (*t) && o != mixbufs.end (*t)) {
o->read_from (*i, nframes);
++i;
++o;
}
while (o != mixbufs.end (*t)) {
o->silence (nframes, 0);
++o;
/* non-audio data will not have been copied by the panner, do it now
* if there are more buffers available than send buffers, ignore them,
* if there are less, copy the last as IO::copy_to_output does. */
for (DataType::iterator t = DataType::begin (); t != DataType::end (); ++t) {
if (*t != DataType::AUDIO) {
BufferSet::iterator o = mixbufs.begin (*t);
BufferSet::iterator i = bufs.begin (*t);
while (i != bufs.end (*t) && o != mixbufs.end (*t)) {
o->read_from (*i, nframes);
++i;
++o;
}
while (o != mixbufs.end (*t)) {
o->silence (nframes, 0);
++o;
}
}
}
}
} else if (role () == Listen) {
/* We're going to the monitor bus, so discard MIDI data */
} else if (role () == Listen || role() == MasterSend) {
/* We're going to the monitor or master bus, so discard MIDI data */
uint32_t const bufs_audio = bufs.count ().get (DataType::AUDIO);
uint32_t const mixbufs_audio = mixbufs.count ().get (DataType::AUDIO);
@ -320,15 +325,51 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
}
}
/* main gain control: * mute & bypass/enable */
/* For a master send, we want the meter to be effectively MeterPostFader
* rather than MeterOutput. But below, we compute a target gain that
* will take mute and solo into account, and apply to mixbufs *before*
* metering, which would make metering equivalent to MeterOutput.
*
* So, for a master send, run our own gain control first (so we see the
* effect in the meters), then meter, then apply any mute/solo-driven gain.
*
* For other internal sends, apply mute/solo-controlled gain, then our
* own gain control, then meter.
*/
if (role() == MasterSend) {
/* apply fader gain automation before running meter */
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_sample + latency, end_sample + latency, nframes);
_amp->run (mixbufs, start_sample + latency, end_sample + latency, speed, nframes, true);
if (_metering) {
if (gain_control ()->get_value () == GAIN_COEFF_ZERO) {
_meter->reset ();
} else {
_meter->run (mixbufs, start_sample, end_sample, speed, nframes, true);
}
}
}
/* tgain reflects muting and soling */
gain_t tgain = target_gain ();
if (tgain != _current_gain) {
/* target gain has changed, fade in/out */
_current_gain = Amp::apply_gain (mixbufs, _session.nominal_sample_rate (), nframes, _current_gain, tgain);
} else if (tgain == GAIN_COEFF_ZERO) {
/* we were quiet last time, and we're still supposed to be quiet. */
_meter->reset ();
/* we were quiet last time, and we're still supposed to be
* quiet. Don't do this for a MasterSend, because its meter is
* effectively MeterPostFader, not MeterOutput, so we don't
* want it to reflect mute/solo-controlled levels.
*/
if (role() != MasterSend || (gain_control()->get_value() == GAIN_COEFF_ZERO)) {
_meter->reset ();
}
Amp::apply_simple_gain (mixbufs, nframes, GAIN_COEFF_ZERO);
return;
} else if (tgain != GAIN_COEFF_UNITY) {
@ -336,15 +377,17 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
Amp::apply_simple_gain (mixbufs, nframes, tgain);
}
/* apply fader gain automation */
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_sample + latency, end_sample + latency, nframes);
_amp->run (mixbufs, start_sample + latency, end_sample + latency, speed, nframes, true);
if (role() != MasterSend) {
/* apply fader gain automation */
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_sample + latency, end_sample + latency, nframes);
_amp->run (mixbufs, start_sample + latency, end_sample + latency, speed, nframes, true);
}
_send_delay->run (mixbufs, start_sample, end_sample, speed, nframes, true);
/* consider metering */
if (_metering) {
if (_metering && role() != MasterSend) {
if (gain_control ()->get_value () == GAIN_COEFF_ZERO) {
_meter->reset ();
} else {

View File

@ -1535,7 +1535,9 @@ Region::_set_state (const XMLNode& node, int version, PropertyChange& what_chang
match.
*/
if ((length().time_domain() == Temporal::AudioTime) && (_sources.front()->length().time_domain() == Temporal::AudioTime) && (length().distance() > _sources.front()->length())) {
_length = timecnt_t (start().distance (_sources.front()->length()), _length.val().position());
std::cerr << "Region " << _name << " has length " << _length.val().str() << " which is longer than its (first?) source's length of " << _sources.front()->length().str() << std::endl;
throw failed_constructor();
// _length = timecnt_t (start().distance (_sources.front()->length()), _length.val().position());
}
}

View File

@ -932,7 +932,7 @@ Route::add_processor (std::shared_ptr<Processor> processor, std::shared_ptr<Proc
assert (processor != _main_outs);
DEBUG_TRACE (DEBUG::Processors, string_compose (
"%1 adding processor %2\n", name(), processor->name()));
"%1 adding processor %2\n", name(), processor->display_name()));
ProcessorList pl;
@ -1901,7 +1901,7 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
}
}
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID=%2 in=%3 out=%4\n",(*p)->name(), (*p)->id(), in, out));
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID=%2 in=%3 out=%4\n",(*p)->display_name(), (*p)->id(), in, out));
configuration.push_back(make_pair(in, out));
if (is_monitor()) {
@ -5380,11 +5380,6 @@ Route::setup_invisible_processors ()
new_processors.push_back (_surround_send);
}
if (Profile->get_livetrax() && _master_send) {
assert (!_master_send->display_to_user());
new_processors.push_back (_master_send);
}
/* MAIN OUTS */
assert (_main_outs);
@ -5407,6 +5402,12 @@ Route::setup_invisible_processors ()
new_processors.insert (meter_point, _meter);
}
if (Profile->get_livetrax() && _master_send) {
assert (!_master_send->display_to_user());
new_processors.insert (main, _master_send);
}
/* Foldback Sends */
for (ProcessorList::iterator i = foldback_sends.begin(); i != foldback_sends.end(); ++i) {
@ -5633,7 +5634,7 @@ Route::setup_invisible_processors ()
DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: setup_invisible_processors\n", _name));
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1\n", (*i)->name ()));
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1\n", (*i)->display_name ()));
}
}