Allow to configure vari-speed resampler quality
This also allows to disable the resampler, effectively disabling varispeed support, for the benefit of adding no additional latency. By default 2 * 16 samples latency are added, due to port-resampler, this is not desirable if Ardour is used as mixer only.
This commit is contained in:
parent
bb4a45ebaf
commit
e863a7dbc9
|
@ -158,7 +158,11 @@ public:
|
|||
|
||||
static pframes_t cycle_nframes () { return _cycle_nframes; }
|
||||
static double speed_ratio () { return _speed_ratio; }
|
||||
|
||||
static uint32_t resampler_quality () { return _resampler_quality; }
|
||||
static uint32_t resampler_latency () { return _resampler_latency; }
|
||||
static bool can_varispeed () { return _resampler_latency > 0; }
|
||||
static void setup_resampler (uint32_t q = 17);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -175,7 +179,6 @@ protected:
|
|||
LatencyRange _private_capture_latency;
|
||||
|
||||
static double _speed_ratio;
|
||||
static const uint32_t _resampler_quality; /* also latency of the resampler */
|
||||
|
||||
private:
|
||||
std::string _name; ///< port short name
|
||||
|
@ -188,6 +191,9 @@ private:
|
|||
*/
|
||||
std::set<std::string> _connections;
|
||||
|
||||
static uint32_t _resampler_quality; // 8 <= q <= 96
|
||||
static uint32_t _resampler_latency; // = _resampler_quality - 1
|
||||
|
||||
void port_connected_or_disconnected (boost::weak_ptr<Port>, boost::weak_ptr<Port>, bool);
|
||||
void signal_drop ();
|
||||
void session_global_drop ();
|
||||
|
|
|
@ -40,6 +40,9 @@ CONFIG_VARIABLE (AutoConnectOption, output_auto_connect, "output-auto-connect",
|
|||
CONFIG_VARIABLE (AutoConnectOption, input_auto_connect, "input-auto-connect", AutoConnectPhysical)
|
||||
CONFIG_VARIABLE (bool, strict_io, "strict-io", true)
|
||||
|
||||
/* 0: off, no varispeed, q: 8..96 */
|
||||
CONFIG_VARIABLE (uint32_t, port_resampler_quality, "port-resampler-quality,", 17)
|
||||
|
||||
/* Connect all physical inputs to a dummy port, this makes raw input data available.
|
||||
* `jack_port_get_buffer (jack_port_by_name (c, "system:capture_1") , n_samples);`
|
||||
* nees to work for input-monitoring (recorder page).
|
||||
|
|
|
@ -42,7 +42,7 @@ AudioPort::AudioPort (const std::string& name, PortFlags flags)
|
|||
, _data (0)
|
||||
{
|
||||
assert (name.find_first_of (':') == string::npos);
|
||||
_src.setup (_resampler_quality);
|
||||
_src.setup (resampler_quality ());
|
||||
_src.set_rrfilt (10);
|
||||
}
|
||||
|
||||
|
|
|
@ -699,9 +699,9 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||
}
|
||||
|
||||
if (_xrun_flag) {
|
||||
/* There still are `Port::resampler_quality () -1` samples in the resampler
|
||||
/* There still are `Port::resampler_latency ()` samples in the resampler
|
||||
* buffer from before the xrun. */
|
||||
_xruns.push_back (_capture_captured + Port::resampler_quality () - 1);
|
||||
_xruns.push_back (_capture_captured + Port::resampler_latency ());
|
||||
}
|
||||
|
||||
_capture_captured += rec_nframes;
|
||||
|
|
|
@ -613,6 +613,8 @@ ARDOUR::init (bool try_optimization, const char* localedir, bool with_gui)
|
|||
}
|
||||
#endif
|
||||
|
||||
Port::setup_resampler (Config->get_port_resampler_quality ());
|
||||
|
||||
setup_hardware_optimization (try_optimization);
|
||||
|
||||
if (Config->get_cpu_dma_latency () >= 0) {
|
||||
|
|
|
@ -47,7 +47,8 @@ pframes_t Port::_global_port_buffer_offset = 0;
|
|||
pframes_t Port::_cycle_nframes = 0;
|
||||
double Port::_speed_ratio = 1.0;
|
||||
std::string Port::state_node_name = X_("Port");
|
||||
const uint32_t Port::_resampler_quality = 17;
|
||||
uint32_t Port::_resampler_quality = 17;
|
||||
uint32_t Port::_resampler_latency = 16; // = _resampler_quality - 1;
|
||||
|
||||
/* a handy define to shorten what would otherwise be a needlessly verbose
|
||||
* repeated phrase
|
||||
|
@ -388,13 +389,9 @@ Port::set_public_latency_range (LatencyRange const& range, bool playback) const
|
|||
if (_port_handle) {
|
||||
LatencyRange r (range);
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort) && sends_output () == playback) {
|
||||
#if 0
|
||||
r.min *= _speed_ratio;
|
||||
r.max *= _speed_ratio;
|
||||
#endif
|
||||
if (type () == DataType::AUDIO) {
|
||||
r.min += (_resampler_quality - 1);
|
||||
r.max += (_resampler_quality - 1);
|
||||
r.min += (_resampler_latency);
|
||||
r.max += (_resampler_latency);
|
||||
}
|
||||
}
|
||||
port_engine.set_latency_range (_port_handle, playback, r);
|
||||
|
@ -449,19 +446,6 @@ Port::public_latency_range (bool playback) const
|
|||
|
||||
if (_port_handle) {
|
||||
r = port_engine.get_latency_range (_port_handle, playback);
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort) && sends_output () == playback) {
|
||||
#if 0
|
||||
r.min /= _speed_ratio;
|
||||
r.max /= _speed_ratio;
|
||||
#endif
|
||||
#if 0
|
||||
/* use value as set by set_public_latency_range */
|
||||
if (type () == DataType::AUDIO) {
|
||||
r.min += (_resampler_quality - 1);
|
||||
r.max += (_resampler_quality - 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::LatencyIO, string_compose (
|
||||
"GET PORT %1: %4 PUBLIC latency range %2 .. %3\n",
|
||||
|
@ -493,8 +477,8 @@ Port::collect_latency_from_backend (LatencyRange& range, bool playback) const
|
|||
if (!AudioEngine::instance()->port_is_mine (*c)) {
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort) && sends_output () == playback) {
|
||||
if (type () == DataType::AUDIO) {
|
||||
lr.min += (_resampler_quality - 1);
|
||||
lr.max += (_resampler_quality - 1);
|
||||
lr.min += (_resampler_latency);
|
||||
lr.max += (_resampler_latency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -542,13 +526,9 @@ Port::get_connected_latency_range (LatencyRange& range, bool playback) const
|
|||
if (remote_port) {
|
||||
lr = port_engine.get_latency_range (remote_port, playback);
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort) && sends_output () == playback) {
|
||||
#if 0
|
||||
lr.min /= _speed_ratio;
|
||||
lr.max /= _speed_ratio;
|
||||
#endif
|
||||
if (type () == DataType::AUDIO) {
|
||||
lr.min += (_resampler_quality - 1);
|
||||
lr.max += (_resampler_quality - 1);
|
||||
lr.min += (_resampler_latency);
|
||||
lr.max += (_resampler_latency);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,13 +706,40 @@ Port::set_state (const XMLNode& node, int)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Port::setup_resampler (uint32_t q)
|
||||
{
|
||||
/* configure at application start (Ardour::init) */
|
||||
static bool setup_done = false;
|
||||
if (setup_done) {
|
||||
return;
|
||||
}
|
||||
setup_done = true;
|
||||
if (q == 0) {
|
||||
/* no vari-speed */
|
||||
_resampler_quality = 0;
|
||||
_resampler_latency = 0;
|
||||
return;
|
||||
}
|
||||
// range constrained in VMResampler::setup
|
||||
if (q < 8) {
|
||||
q = 8;
|
||||
}
|
||||
if (q > 96) {
|
||||
q = 96;
|
||||
}
|
||||
_resampler_quality = q;
|
||||
_resampler_latency = q - 1;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
Port::set_speed_ratio (double s) {
|
||||
/* see VMResampler::set_rratio() for min/max range */
|
||||
if (s == 0.0) {
|
||||
if (s == 0.0 || !can_varispeed ()) {
|
||||
/* no resampling when stopped */
|
||||
_speed_ratio = 1.0;
|
||||
} else {
|
||||
/* see VMResampler::set_rratio() for min/max range */
|
||||
_speed_ratio = std::min ((double) Config->get_max_transport_speed(), std::max (0.02, fabs (s)));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue