annotate dsp/rateconversion/TestResampler.cpp @ 367:0721657fdd1d

Fix scaling on downsampling, another test
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 14 Oct 2013 16:20:00 +0100
parents 767947956fc1
children a4aa37f7af28
rev   line source
c@362 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@362 2
c@362 3 #include "Resampler.h"
c@362 4
c@362 5 #include <iostream>
c@362 6
c@362 7 #include <cmath>
c@362 8
c@362 9 #define BOOST_TEST_DYN_LINK
c@362 10 #define BOOST_TEST_MAIN
c@362 11
c@362 12 #include <boost/test/unit_test.hpp>
c@362 13
c@362 14 BOOST_AUTO_TEST_SUITE(TestResampler)
c@362 15
c@362 16 using std::cout;
c@362 17 using std::endl;
c@363 18 using std::vector;
c@363 19
c@363 20 void
c@363 21 testResamplerOneShot(int sourceRate,
c@363 22 int targetRate,
c@363 23 int n,
c@363 24 double *in,
c@363 25 int m,
c@366 26 double *expected,
c@366 27 int skip)
c@363 28 {
c@363 29 vector<double> resampled = Resampler::resample(sourceRate, targetRate,
c@363 30 in, n);
c@366 31 if (skip == 0) {
c@366 32 BOOST_CHECK_EQUAL(resampled.size(), m);
c@366 33 }
c@363 34 for (int i = 0; i < m; ++i) {
c@366 35 BOOST_CHECK_SMALL(resampled[i + skip] - expected[i], 1e-8);
c@363 36 }
c@363 37 }
c@362 38
c@362 39 void
c@362 40 testResampler(int sourceRate,
c@362 41 int targetRate,
c@362 42 int n,
c@362 43 double *in,
c@362 44 int m,
c@362 45 double *expected)
c@362 46 {
c@364 47 // Here we provide the input in chunks (of varying size)
c@363 48
c@362 49 Resampler r(sourceRate, targetRate);
c@362 50 int latency = r.getLatency();
c@362 51
c@362 52 int m1 = m + latency;
c@362 53 int n1 = int((m1 * sourceRate) / targetRate);
c@362 54
c@362 55 double *inPadded = new double[n1];
c@362 56 double *outPadded = new double[m1];
c@362 57
c@362 58 for (int i = 0; i < n1; ++i) {
c@362 59 if (i < n) inPadded[i] = in[i];
c@362 60 else inPadded[i] = 0.0;
c@362 61 }
c@362 62
c@362 63 for (int i = 0; i < m1; ++i) {
c@362 64 outPadded[i] = -999.0;
c@362 65 }
c@362 66
c@364 67 int chunkSize = 1;
c@364 68 int got = 0;
c@364 69 int i = 0;
c@362 70
c@364 71 while (true) {
c@364 72 got += r.process(inPadded + i, outPadded + got, chunkSize);
c@364 73 i = i + chunkSize;
c@364 74 chunkSize = chunkSize + 1;
c@366 75 if (i >= n1) {
c@364 76 break;
c@364 77 } else if (i + chunkSize >= n1) {
c@364 78 chunkSize = n1 - i;
c@366 79 } else if (chunkSize > 15) {
c@366 80 chunkSize = 1;
c@364 81 }
c@364 82 }
c@364 83
c@366 84 BOOST_CHECK_EQUAL(got, m1);
c@362 85
c@362 86 for (int i = latency; i < m1; ++i) {
c@363 87 BOOST_CHECK_SMALL(outPadded[i] - expected[i-latency], 1e-8);
c@362 88 }
c@366 89
c@362 90 delete[] outPadded;
c@362 91 delete[] inPadded;
c@362 92 }
c@362 93
c@365 94 BOOST_AUTO_TEST_CASE(sameRateOneShot)
c@365 95 {
c@365 96 double d[] = { 0, 0.1, -0.3, -0.4, -0.3, 0, 0.5, 0.2, 0.8, -0.1 };
c@366 97 testResamplerOneShot(4, 4, 10, d, 10, d, 0);
c@365 98 }
c@365 99
c@362 100 BOOST_AUTO_TEST_CASE(sameRate)
c@362 101 {
c@362 102 double d[] = { 0, 0.1, -0.3, -0.4, -0.3, 0, 0.5, 0.2, 0.8, -0.1 };
c@362 103 testResampler(4, 4, 10, d, 10, d);
c@362 104 }
c@362 105
c@366 106 BOOST_AUTO_TEST_CASE(interpolatedMisc)
c@366 107 {
c@366 108 // Interpolating any signal by N should give a signal in which
c@366 109 // every Nth sample is the original signal
c@366 110 double in[] = { 0, 0.1, -0.3, -0.4, -0.3, 0, 0.5, 0.2, 0.8, -0.1 };
c@366 111 int n = sizeof(in)/sizeof(in[0]);
c@366 112 for (int factor = 2; factor < 10; ++factor) {
c@366 113 vector<double> out = Resampler::resample(6, 6 * factor, in, n);
c@366 114 for (int i = 0; i < n; ++i) {
c@366 115 BOOST_CHECK_SMALL(out[i * factor] - in[i], 1e-5);
c@366 116 }
c@366 117 }
c@366 118 }
c@366 119
c@366 120 BOOST_AUTO_TEST_CASE(interpolatedSine)
c@366 121 {
c@367 122 // Interpolating a sinusoid should give us a sinusoid, once we've
c@367 123 // dropped the first few samples
c@366 124 double in[1000];
c@366 125 double out[2000];
c@366 126 for (int i = 0; i < 1000; ++i) {
c@366 127 in[i] = sin(i * M_PI / 2.0);
c@366 128 }
c@366 129 for (int i = 0; i < 2000; ++i) {
c@366 130 out[i] = sin(i * M_PI / 4.0);
c@366 131 }
c@367 132 testResamplerOneShot(8, 16, 1000, in, 200, out, 512);
c@367 133 }
c@367 134
c@367 135 BOOST_AUTO_TEST_CASE(decimatedSine)
c@367 136 {
c@367 137 // Decimating a sinusoid should give us a sinusoid, once we've
c@367 138 // dropped the first few samples
c@367 139 double in[2000];
c@367 140 double out[1000];
c@367 141 for (int i = 0; i < 2000; ++i) {
c@367 142 in[i] = sin(i * M_PI / 8.0);
c@367 143 }
c@367 144 for (int i = 0; i < 1000; ++i) {
c@367 145 out[i] = sin(i * M_PI / 4.0);
c@367 146 }
c@367 147 testResamplerOneShot(16, 8, 2000, in, 200, out, 256);
c@366 148 }
c@366 149
c@362 150 BOOST_AUTO_TEST_SUITE_END()
c@362 151