Prepare dedicated Disk-reader de-click gain-stage
This allows to specify a shorter fade-duration than default Amp::apply_gain(), also allows to unroll and vectorize the loop
This commit is contained in:
parent
3c96ba1de6
commit
18af4dd55a
@ -94,7 +94,7 @@ public:
|
||||
void reset_tracker ();
|
||||
|
||||
bool declick_in_progress () const {
|
||||
return _declick_gain != 0; // declick-out
|
||||
return _declick_amp.gain() != 0; // declick-out
|
||||
}
|
||||
|
||||
static void set_midi_readahead_samples (samplecnt_t samples_ahead) { midi_readahead = samples_ahead; }
|
||||
@ -125,6 +125,22 @@ protected:
|
||||
|
||||
int add_channel_to (boost::shared_ptr<ChannelList>, uint32_t how_many);
|
||||
|
||||
class DeclickAmp
|
||||
{
|
||||
public:
|
||||
DeclickAmp (samplecnt_t sample_rate);
|
||||
|
||||
void apply_gain (AudioBuffer& buf, samplecnt_t n_samples, const float target);
|
||||
|
||||
float gain () const { return _g; }
|
||||
void set_gain (float g) { _g = g; }
|
||||
|
||||
private:
|
||||
float _a;
|
||||
float _l;
|
||||
float _g;
|
||||
};
|
||||
|
||||
private:
|
||||
/** The number of samples by which this diskstream's output should be delayed
|
||||
with respect to the transport sample. This is used for latency compensation.
|
||||
@ -135,7 +151,8 @@ private:
|
||||
IOChange input_change_pending;
|
||||
samplepos_t file_sample[DataType::num_types];
|
||||
|
||||
gain_t _declick_gain;
|
||||
DeclickAmp _declick_amp;
|
||||
sampleoffset_t _declick_offs;
|
||||
|
||||
int _do_refill_with_alloc (bool partial_fill);
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "pbd/memento_command.h"
|
||||
#include "pbd/playback_buffer.h"
|
||||
|
||||
#include "ardour/amp.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/audioplaylist.h"
|
||||
#include "ardour/audio_buffer.h"
|
||||
@ -57,7 +58,8 @@ DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f)
|
||||
, overwrite_sample (0)
|
||||
, _pending_overwrite (false)
|
||||
, overwrite_queued (false)
|
||||
, _declick_gain (0)
|
||||
, _declick_amp (s.nominal_sample_rate ())
|
||||
, _declick_offs (0)
|
||||
{
|
||||
file_sample[DataType::AUDIO] = 0;
|
||||
file_sample[DataType::MIDI] = 0;
|
||||
@ -1400,3 +1402,54 @@ DiskReader::set_no_disk_output (bool yn)
|
||||
*/
|
||||
_no_disk_output = yn;
|
||||
}
|
||||
|
||||
DiskReader::DeclickAmp::DeclickAmp (samplecnt_t sample_rate)
|
||||
{
|
||||
_a = 2200.f / (gain_t)sample_rate;
|
||||
_l = -log1p (_a);
|
||||
_g = 0;
|
||||
}
|
||||
|
||||
void
|
||||
DiskReader::DeclickAmp::apply_gain (AudioBuffer& buf, samplecnt_t n_samples, const float target)
|
||||
{
|
||||
if (n_samples == 0) {
|
||||
return;
|
||||
}
|
||||
float g = _g;
|
||||
|
||||
if (g == target) {
|
||||
Amp::apply_simple_gain (buf, n_samples, target, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
const float a = _a;
|
||||
Sample* const buffer = buf.data ();
|
||||
|
||||
#define MAX_NPROC 16
|
||||
uint32_t remain = n_samples;
|
||||
uint32_t offset = 0;
|
||||
while (remain > 0) {
|
||||
uint32_t n_proc = remain > MAX_NPROC ? MAX_NPROC : remain;
|
||||
for (uint32_t i = 0; i < n_proc; ++i) {
|
||||
buffer[offset + i] *= g;
|
||||
}
|
||||
#if 1
|
||||
g += a * (target - g);
|
||||
#else /* accurate exponential fade */
|
||||
if (n_proc == MAX_NPROC) {
|
||||
g += a * (target - g);
|
||||
} else {
|
||||
g = target - (target - g) * expf (_l * n_proc / MAX_NPROC);
|
||||
}
|
||||
#endif
|
||||
remain -= n_proc;
|
||||
offset += n_proc;
|
||||
}
|
||||
|
||||
if (fabsf (g - target) < /* GAIN_COEFF_DELTA */ 1e-5) {
|
||||
_g = target;
|
||||
} else {
|
||||
_g = g;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user