mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 16:24:57 +01:00
Xinterpolation.*: Add old fixed point and double linear interpolation as alternatives
git-svn-id: svn://localhost/ardour2/branches/3.0@5258 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
47e5690552
commit
dd84d5312e
8 changed files with 385 additions and 76 deletions
|
|
@ -146,7 +146,7 @@ class AudioDiskstream : public Diskstream
|
|||
}
|
||||
}
|
||||
|
||||
LibSamplerateInterpolation interpolation;
|
||||
FixedPointLinearInterpolation interpolation;
|
||||
|
||||
XMLNode* deprecated_io_node;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,18 +8,90 @@
|
|||
|
||||
namespace ARDOUR {
|
||||
|
||||
class LibSamplerateInterpolation {
|
||||
protected:
|
||||
double _speed;
|
||||
class Interpolation {
|
||||
protected:
|
||||
double _speed, _target_speed;
|
||||
|
||||
public:
|
||||
Interpolation () { _speed = 1.0; }
|
||||
|
||||
void set_speed (double new_speed) { _speed = new_speed; }
|
||||
void set_target_speed (double new_speed) { _target_speed = new_speed; }
|
||||
|
||||
double target_speed() const { return _target_speed; }
|
||||
double speed() const { return _speed; }
|
||||
|
||||
void add_channel_to (int input_buffer_size, int output_buffer_size) {}
|
||||
void remove_channel_from () {}
|
||||
|
||||
nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output) {}
|
||||
void reset () {}
|
||||
};
|
||||
|
||||
// 40.24 fixpoint math
|
||||
#define FIXPOINT_ONE 0x1000000
|
||||
|
||||
class FixedPointLinearInterpolation : public Interpolation {
|
||||
protected:
|
||||
/// speed in fixed point math
|
||||
uint64_t phi;
|
||||
|
||||
/// target speed in fixed point math
|
||||
uint64_t target_phi;
|
||||
|
||||
std::vector<uint64_t> last_phase;
|
||||
|
||||
// Fixed point is just an integer with an implied scaling factor.
|
||||
// In 40.24 the scaling factor is 2^24 = 16777216,
|
||||
// so a value of 10*2^24 (in integer space) is equivalent to 10.0.
|
||||
//
|
||||
// The advantage is that addition and modulus [like x = (x + y) % 2^40]
|
||||
// have no rounding errors and no drift, and just require a single integer add.
|
||||
// (swh)
|
||||
|
||||
std::vector<SRC_STATE*> state;
|
||||
std::vector<SRC_DATA*> data;
|
||||
|
||||
int error;
|
||||
|
||||
void reset_state ();
|
||||
|
||||
public:
|
||||
static const int64_t fractional_part_mask = 0xFFFFFF;
|
||||
static const Sample binary_scaling_factor = 16777216.0f;
|
||||
|
||||
public:
|
||||
FixedPointLinearInterpolation () : phi (FIXPOINT_ONE), target_phi (FIXPOINT_ONE) {}
|
||||
|
||||
void set_speed (double new_speed) {
|
||||
target_phi = (uint64_t) (FIXPOINT_ONE * fabs(new_speed));
|
||||
phi = target_phi;
|
||||
}
|
||||
|
||||
void add_channel_to (int input_buffer_size, int output_buffer_size);
|
||||
void remove_channel_from ();
|
||||
|
||||
nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output);
|
||||
void reset ();
|
||||
};
|
||||
|
||||
class LinearInterpolation : public Interpolation {
|
||||
protected:
|
||||
// the idea is that when the speed is not 1.0, we have to
|
||||
// interpolate between samples and then we have to store where we thought we were.
|
||||
// rather than being at sample N or N+1, we were at N+0.8792922
|
||||
std::vector<double> phase;
|
||||
|
||||
public:
|
||||
void add_channel_to (int input_buffer_size, int output_buffer_size);
|
||||
void remove_channel_from ();
|
||||
|
||||
nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output);
|
||||
void reset ();
|
||||
};
|
||||
|
||||
class LibSamplerateInterpolation : public Interpolation {
|
||||
protected:
|
||||
std::vector<SRC_STATE*> state;
|
||||
std::vector<SRC_DATA*> data;
|
||||
|
||||
int error;
|
||||
|
||||
void reset_state ();
|
||||
|
||||
public:
|
||||
LibSamplerateInterpolation ();
|
||||
~LibSamplerateInterpolation ();
|
||||
|
||||
|
|
@ -31,8 +103,9 @@ public:
|
|||
void remove_channel_from ();
|
||||
|
||||
nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output);
|
||||
void reset() { reset_state (); }
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1011,7 +1011,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
volatile double _transport_speed;
|
||||
double _last_transport_speed;
|
||||
double _target_transport_speed;
|
||||
LibSamplerateInterpolation interpolation;
|
||||
FixedPointLinearInterpolation interpolation;
|
||||
|
||||
bool auto_play_legal;
|
||||
nframes_t _last_slave_transport_frame;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,141 @@
|
|||
|
||||
using namespace ARDOUR;
|
||||
|
||||
LibSamplerateInterpolation::LibSamplerateInterpolation() : _speed (1.0L), state (0)
|
||||
nframes_t
|
||||
FixedPointLinearInterpolation::interpolate (int channel, nframes_t nframes, Sample *input, Sample *output)
|
||||
{
|
||||
// the idea behind phase is that when the speed is not 1.0, we have to
|
||||
// interpolate between samples and then we have to store where we thought we were.
|
||||
// rather than being at sample N or N+1, we were at N+0.8792922
|
||||
// so the "phase" element, if you want to think about this way,
|
||||
// varies from 0 to 1, representing the "offset" between samples
|
||||
uint64_t phase = last_phase[channel];
|
||||
|
||||
// acceleration
|
||||
int64_t phi_delta;
|
||||
|
||||
// phi = fixed point speed
|
||||
if (phi != target_phi) {
|
||||
phi_delta = ((int64_t)(target_phi - phi)) / nframes;
|
||||
} else {
|
||||
phi_delta = 0;
|
||||
}
|
||||
|
||||
// index in the input buffers
|
||||
nframes_t i = 0;
|
||||
|
||||
for (nframes_t outsample = 0; outsample < nframes; ++outsample) {
|
||||
i = phase >> 24;
|
||||
Sample fractional_phase_part = (phase & fractional_part_mask) / binary_scaling_factor;
|
||||
|
||||
if (input && output) {
|
||||
// Linearly interpolate into the output buffer
|
||||
// using fixed point math
|
||||
output[outsample] =
|
||||
input[i] * (1.0f - fractional_phase_part) +
|
||||
input[i+1] * fractional_phase_part;
|
||||
}
|
||||
|
||||
phase += phi + phi_delta;
|
||||
}
|
||||
|
||||
last_phase[channel] = (phase & fractional_part_mask);
|
||||
|
||||
// playback distance
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
FixedPointLinearInterpolation::add_channel_to (int input_buffer_size, int output_buffer_size)
|
||||
{
|
||||
last_phase.push_back (0);
|
||||
}
|
||||
|
||||
void
|
||||
FixedPointLinearInterpolation::remove_channel_from ()
|
||||
{
|
||||
last_phase.pop_back ();
|
||||
}
|
||||
|
||||
void
|
||||
FixedPointLinearInterpolation::reset()
|
||||
{
|
||||
for(int i = 0; i <= last_phase.size(); i++) {
|
||||
last_phase[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nframes_t
|
||||
LinearInterpolation::interpolate (int channel, nframes_t nframes, Sample *input, Sample *output)
|
||||
{
|
||||
// index in the input buffers
|
||||
nframes_t i = 0;
|
||||
|
||||
double acceleration;
|
||||
double distance = 0.0;
|
||||
|
||||
if (_speed != _target_speed) {
|
||||
acceleration = _target_speed - _speed;
|
||||
} else {
|
||||
acceleration = 0.0;
|
||||
}
|
||||
|
||||
printf("phase before: %lf\n", phase[channel]);
|
||||
distance = phase[channel];
|
||||
for (nframes_t outsample = 0; outsample < nframes; ++outsample) {
|
||||
i = distance;
|
||||
Sample fractional_phase_part = distance - i;
|
||||
if (fractional_phase_part >= 1.0) {
|
||||
fractional_phase_part -= 1.0;
|
||||
i++;
|
||||
}
|
||||
//printf("I: %u, distance: %lf, fractional_phase_part: %lf\n", i, distance, fractional_phase_part);
|
||||
|
||||
if (input && output) {
|
||||
// Linearly interpolate into the output buffer
|
||||
output[outsample] =
|
||||
input[i] * (1.0f - fractional_phase_part) +
|
||||
input[i+1] * fractional_phase_part;
|
||||
}
|
||||
//printf("distance before: %lf\n", distance);
|
||||
distance += _speed + acceleration;
|
||||
//printf("distance after: %lf, _speed: %lf\n", distance, _speed);
|
||||
}
|
||||
|
||||
printf("before assignment: i: %d, distance: %lf\n", i, distance);
|
||||
i = floor(distance);
|
||||
printf("after assignment: i: %d, distance: %16lf\n", i, distance);
|
||||
phase[channel] = distance - floor(distance);
|
||||
printf("speed: %16lf, i after: %d, distance after: %16lf, phase after: %16lf\n", _speed, i, distance, phase[channel]);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
LinearInterpolation::add_channel_to (int input_buffer_size, int output_buffer_size)
|
||||
{
|
||||
phase.push_back (0.0);
|
||||
}
|
||||
|
||||
void
|
||||
LinearInterpolation::remove_channel_from ()
|
||||
{
|
||||
phase.pop_back ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinearInterpolation::reset()
|
||||
{
|
||||
for(int i = 0; i <= phase.size(); i++) {
|
||||
phase[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
LibSamplerateInterpolation::LibSamplerateInterpolation() : state (0)
|
||||
{
|
||||
_speed = 1.0;
|
||||
}
|
||||
|
||||
LibSamplerateInterpolation::~LibSamplerateInterpolation()
|
||||
|
|
@ -77,12 +210,12 @@ LibSamplerateInterpolation::interpolate (int channel, nframes_t nframes, Sample
|
|||
return 0;
|
||||
}
|
||||
|
||||
data[channel]->data_in = input;
|
||||
data[channel]->data_out = output;
|
||||
data[channel]->data_in = input;
|
||||
data[channel]->data_out = output;
|
||||
|
||||
data[channel]->input_frames = nframes * _speed;
|
||||
data[channel]->output_frames = nframes;
|
||||
data[channel]->src_ratio = 1.0/_speed;
|
||||
data[channel]->src_ratio = 1.0/_speed;
|
||||
|
||||
if ((error = src_process (state[channel], data[channel]))) {
|
||||
printf ("\nError : %s\n\n", src_strerror (error));
|
||||
|
|
|
|||
|
|
@ -147,6 +147,8 @@ Session::Session (AudioEngine &eng,
|
|||
{
|
||||
bool new_session;
|
||||
|
||||
interpolation.add_channel_to (0, 0);
|
||||
|
||||
if (!eng.connected()) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
|
@ -231,6 +233,8 @@ Session::Session (AudioEngine &eng,
|
|||
{
|
||||
bool new_session;
|
||||
|
||||
interpolation.add_channel_to (0, 0);
|
||||
|
||||
if (!eng.connected()) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -327,8 +327,7 @@ Session::process_with_events (nframes_t nframes)
|
|||
} else {
|
||||
interpolation.set_target_speed (_target_transport_speed);
|
||||
interpolation.set_speed (_transport_speed);
|
||||
//FIXME frames_moved = (long) interpolation.interpolate (nframes, 0, 0);
|
||||
frames_moved = _transport_speed * nframes;
|
||||
frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
|
||||
}
|
||||
|
||||
end_frame = _transport_frame + (nframes_t)frames_moved;
|
||||
|
|
@ -849,8 +848,7 @@ Session::process_without_events (nframes_t nframes)
|
|||
} else {
|
||||
interpolation.set_target_speed (_target_transport_speed);
|
||||
interpolation.set_speed (_transport_speed);
|
||||
//FIXME frames_moved = (long) interpolation.interpolate (nframes, 0, 0);
|
||||
frames_moved = _transport_speed * nframes;
|
||||
frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
|
||||
}
|
||||
|
||||
if (process_routes (nframes)) {
|
||||
|
|
|
|||
|
|
@ -9,63 +9,160 @@ using namespace ARDOUR;
|
|||
void
|
||||
InterpolationTest::linearInterpolationTest ()
|
||||
{
|
||||
cout << "\nLinear Interpolation Test\n";
|
||||
cout << "\nSpeed: 1.0";
|
||||
interpolation.set_speed (1.0);
|
||||
nframes_t result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
nframes_t result = 0;
|
||||
cout << "\nLinear Interpolation Test\n";
|
||||
|
||||
cout << "\nSpeed: 1/3";
|
||||
for (int i = 0; i < NUM_SAMPLES - 1024;) {
|
||||
linear.set_speed (double(1.0)/double(3.0));
|
||||
linear.set_target_speed (double(1.0)/double(3.0));
|
||||
printf ("Interpolate: input: %d, output: %d, i: %d\n", input + i, output + i, i);
|
||||
result = linear.interpolate (0, 1024, input + i, output + i);
|
||||
printf ("Result: %d\n", result);
|
||||
//CPPUNIT_ASSERT_EQUAL ((uint32_t)((NUM_SAMPLES - 100) * interpolation.speed()), result);
|
||||
i += result;
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 1.0";
|
||||
linear.reset();
|
||||
linear.set_speed (1.0);
|
||||
linear.set_target_speed (linear.speed());
|
||||
result = linear.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * linear.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES; i += INTERVAL) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 0.5";
|
||||
linear.reset();
|
||||
linear.set_speed (0.5);
|
||||
linear.set_target_speed (linear.speed());
|
||||
result = linear.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * linear.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES; i += (INTERVAL / linear.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 0.2";
|
||||
linear.reset();
|
||||
linear.set_speed (0.2);
|
||||
linear.set_target_speed (linear.speed());
|
||||
result = linear.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * linear.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 0.02";
|
||||
linear.reset();
|
||||
linear.set_speed (0.02);
|
||||
linear.set_target_speed (linear.speed());
|
||||
result = linear.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * linear.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 0.002";
|
||||
linear.reset();
|
||||
linear.set_speed (0.002);
|
||||
linear.set_target_speed (linear.speed());
|
||||
result = linear.interpolate (0, NUM_SAMPLES, input, output);
|
||||
linear.speed();
|
||||
printf("BOOM!: expexted: %d, result = %d\n", (nframes_t)(NUM_SAMPLES * linear.speed()), result);
|
||||
CPPUNIT_ASSERT_EQUAL ((nframes_t)(NUM_SAMPLES * linear.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 2.0";
|
||||
linear.reset();
|
||||
linear.set_speed (2.0);
|
||||
linear.set_target_speed (linear.speed());
|
||||
result = linear.interpolate (0, NUM_SAMPLES / 2, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES / 2 * linear.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES / 2; i += (INTERVAL / linear.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 10.0";
|
||||
linear.set_speed (10.0);
|
||||
linear.set_target_speed (linear.speed());
|
||||
result = linear.interpolate (0, NUM_SAMPLES / 10, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES / 10 * linear.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES / 10; i += (INTERVAL / linear.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
/*
|
||||
for (int i=0; i < NUM_SAMPLES; ++i) {
|
||||
cout << "input[" << i << "] = " << input[i] << " output[" << i << "] = " << output[i] << endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
InterpolationTest::libSamplerateInterpolationTest ()
|
||||
{
|
||||
nframes_t result;
|
||||
|
||||
cout << "\nLibSamplerate Interpolation Test\n";
|
||||
/*
|
||||
cout << "\nSpeed: 1.0";
|
||||
interpolation.set_speed (1.0);
|
||||
for (int i = 0; i < NUM_SAMPLES;) {
|
||||
interpolation.set_speed (1.0);
|
||||
result = interpolation.interpolate (0, INTERVAL/10, input + i, output + i);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(INTERVAL/10 * interpolation.speed()), result);
|
||||
i += result;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_SAMPLES; i += INTERVAL) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i+1]);
|
||||
}
|
||||
*/
|
||||
for (int i=0; i < NUM_SAMPLES; ++i) {
|
||||
cout << "input[" << i << "] = " << input[i] << " output[" << i << "] = " << output[i] << endl;
|
||||
|
||||
cout << "\nSpeed: 0.5";
|
||||
for (int i = 0; i < NUM_SAMPLES;) {
|
||||
interpolation.set_speed (0.5);
|
||||
printf ("Interpolate: input: %d, output: %d, i: %d\n", input + i, output + i, i);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES - 100, input + i, output + i);
|
||||
printf ("Result: %d\n", result);
|
||||
//CPPUNIT_ASSERT_EQUAL ((uint32_t)((NUM_SAMPLES - 100) * interpolation.speed()), result);
|
||||
//i += result;
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < NUM_SAMPLES; i += INTERVAL) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i+1]);
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 0.5";
|
||||
interpolation.set_speed (0.5);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES; i += (INTERVAL / interpolation.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 0.2";
|
||||
interpolation.set_speed (0.2);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 0.02";
|
||||
interpolation.set_speed (0.02);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 0.002";
|
||||
interpolation.set_speed (0.002);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 2.0";
|
||||
interpolation.set_speed (2.0);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES / 2, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES / 2 * interpolation.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES / 2; i += (INTERVAL / interpolation.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 10.0";
|
||||
interpolation.set_speed (10.0);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES / 10, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES / 10 * interpolation.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES / 10; i += (INTERVAL / interpolation.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
/*
|
||||
for (int i=0; i < NUM_SAMPLES; ++i) {
|
||||
cout << "input[" << i << "] = " << input[i] << " output[" << i << "] = " << output[i] << endl;
|
||||
for (int i=0; i < NUM_SAMPLES; ++i) {
|
||||
cout << "input[" << i << "] = " << input[i] << " output[" << i << "] = " << output[i] << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
cout << "\nSpeed: 0.2";
|
||||
interpolation.set_speed (0.2);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 0.02";
|
||||
interpolation.set_speed (0.02);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 0.002";
|
||||
interpolation.set_speed (0.002);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES * interpolation.speed()), result);
|
||||
|
||||
cout << "\nSpeed: 2.0";
|
||||
interpolation.set_speed (2.0);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES / 2, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES / 2 * interpolation.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES / 2; i += (INTERVAL / interpolation.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
|
||||
cout << "\nSpeed: 10.0";
|
||||
interpolation.set_speed (10.0);
|
||||
result = interpolation.interpolate (0, NUM_SAMPLES / 10, input, output);
|
||||
CPPUNIT_ASSERT_EQUAL ((uint32_t)(NUM_SAMPLES / 10 * interpolation.speed()), result);
|
||||
for (int i = 0; i < NUM_SAMPLES / 10; i += (INTERVAL / interpolation.speed() +0.5)) {
|
||||
CPPUNIT_ASSERT_EQUAL (1.0f, output[i]);
|
||||
}
|
||||
/*
|
||||
for (int i=0; i < NUM_SAMPLES; ++i) {
|
||||
cout << "input[" << i << "] = " << input[i] << " output[" << i << "] = " << output[i] << endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,15 +27,17 @@ class InterpolationTest : public CppUnit::TestFixture
|
|||
{
|
||||
CPPUNIT_TEST_SUITE(InterpolationTest);
|
||||
CPPUNIT_TEST(linearInterpolationTest);
|
||||
//CPPUNIT_TEST(libSamplerateInterpolationTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
#define NUM_SAMPLES 100000000
|
||||
#define NUM_SAMPLES 1000000
|
||||
#define INTERVAL 100
|
||||
|
||||
ARDOUR::Sample input[NUM_SAMPLES];
|
||||
ARDOUR::Sample output[NUM_SAMPLES];
|
||||
|
||||
ARDOUR::Interpolation interpolation;
|
||||
ARDOUR::LinearInterpolation linear;
|
||||
ARDOUR::LibSamplerateInterpolation interpolation;
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -48,6 +50,7 @@ class InterpolationTest : public CppUnit::TestFixture
|
|||
}
|
||||
output[i] = 0.0f;
|
||||
}
|
||||
linear.add_channel_to (NUM_SAMPLES, NUM_SAMPLES);
|
||||
interpolation.add_channel_to (NUM_SAMPLES, NUM_SAMPLES);
|
||||
}
|
||||
|
||||
|
|
@ -55,5 +58,6 @@ class InterpolationTest : public CppUnit::TestFixture
|
|||
}
|
||||
|
||||
void linearInterpolationTest();
|
||||
void libSamplerateInterpolationTest();
|
||||
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue