annotate base/test/TestColumnOp.h @ 1346:75ad55315db4 3.0-integration

More work on getting tests (especially file encoding ones) running on Windows. Various problems here to do with interaction with test filenames in Hg repos
author Chris Cannam
date Fri, 06 Jan 2017 15:44:55 +0000
parents 7cff8367d9b1
children bd1eb56df8d5
rev   line source
Chris@1265 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1265 2
Chris@1265 3 /*
Chris@1265 4 Sonic Visualiser
Chris@1265 5 An audio file viewer and annotation editor.
Chris@1265 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1265 7
Chris@1265 8 This program is free software; you can redistribute it and/or
Chris@1265 9 modify it under the terms of the GNU General Public License as
Chris@1265 10 published by the Free Software Foundation; either version 2 of the
Chris@1265 11 License, or (at your option) any later version. See the file
Chris@1265 12 COPYING included with this distribution for more information.
Chris@1265 13 */
Chris@1265 14
Chris@1265 15 #ifndef TEST_COLUMN_OP_H
Chris@1265 16 #define TEST_COLUMN_OP_H
Chris@1265 17
Chris@1265 18 #include "../ColumnOp.h"
Chris@1265 19
Chris@1265 20 #include <QObject>
Chris@1265 21 #include <QtTest>
Chris@1265 22 #include <QDir>
Chris@1265 23
Chris@1265 24 #include <iostream>
Chris@1265 25
Chris@1304 26 //#define REPORT 1
Chris@1304 27
Chris@1265 28 using namespace std;
Chris@1265 29
Chris@1265 30 class TestColumnOp : public QObject
Chris@1265 31 {
Chris@1265 32 Q_OBJECT
Chris@1265 33
Chris@1265 34 typedef ColumnOp C;
Chris@1265 35 typedef ColumnOp::Column Column;
Chris@1266 36 typedef vector<double> BinMapping;
Chris@1266 37
Chris@1269 38 #ifdef REPORT
Chris@1266 39 template <typename T>
Chris@1266 40 void report(vector<T> v) {
Chris@1266 41 cerr << "Vector is: [ ";
Chris@1266 42 for (int i = 0; i < int(v.size()); ++i) {
Chris@1266 43 if (i > 0) cerr << ", ";
Chris@1266 44 cerr << v[i];
Chris@1266 45 }
Chris@1266 46 cerr << " ]\n";
Chris@1266 47 }
Chris@1269 48 #else
Chris@1269 49 template <typename T>
Chris@1269 50 void report(vector<T> ) { }
Chris@1269 51 #endif
Chris@1266 52
Chris@1265 53 private slots:
Chris@1265 54 void applyGain() {
Chris@1265 55 QCOMPARE(C::applyGain({}, 1.0), Column());
Chris@1265 56 Column c { 1, 2, 3, -4, 5, 6 };
Chris@1265 57 Column actual(C::applyGain(c, 1.5));
Chris@1265 58 Column expected { 1.5, 3, 4.5, -6, 7.5, 9 };
Chris@1265 59 QCOMPARE(actual, expected);
Chris@1265 60 actual = C::applyGain(c, 1.0);
Chris@1265 61 QCOMPARE(actual, c);
Chris@1265 62 actual = C::applyGain(c, 0.0);
Chris@1265 63 expected = { 0, 0, 0, 0, 0, 0 };
Chris@1265 64 QCOMPARE(actual, expected);
Chris@1265 65 }
Chris@1265 66
Chris@1265 67 void fftScale() {
Chris@1265 68 QCOMPARE(C::fftScale({}, 2.0), Column());
Chris@1265 69 Column c { 1, 2, 3, -4, 5 };
Chris@1265 70 Column actual(C::fftScale(c, 8));
Chris@1265 71 Column expected { 0.25, 0.5, 0.75, -1, 1.25 };
Chris@1265 72 QCOMPARE(actual, expected);
Chris@1265 73 }
Chris@1265 74
Chris@1265 75 void isPeak_null() {
Chris@1265 76 QVERIFY(!C::isPeak({}, 0));
Chris@1265 77 QVERIFY(!C::isPeak({}, 1));
Chris@1265 78 QVERIFY(!C::isPeak({}, -1));
Chris@1265 79 }
Chris@1265 80
Chris@1265 81 void isPeak_obvious() {
Chris@1265 82 Column c { 0.4, 0.5, 0.3 };
Chris@1265 83 QVERIFY(!C::isPeak(c, 0));
Chris@1265 84 QVERIFY(C::isPeak(c, 1));
Chris@1265 85 QVERIFY(!C::isPeak(c, 2));
Chris@1265 86 }
Chris@1265 87
Chris@1265 88 void isPeak_edges() {
Chris@1265 89 Column c { 0.5, 0.4, 0.3 };
Chris@1265 90 QVERIFY(C::isPeak(c, 0));
Chris@1265 91 QVERIFY(!C::isPeak(c, 1));
Chris@1265 92 QVERIFY(!C::isPeak(c, 2));
Chris@1265 93 QVERIFY(!C::isPeak(c, 3));
Chris@1265 94 QVERIFY(!C::isPeak(c, -1));
Chris@1265 95 c = { 1.4, 1.5 };
Chris@1265 96 QVERIFY(!C::isPeak(c, 0));
Chris@1265 97 QVERIFY(C::isPeak(c, 1));
Chris@1265 98 }
Chris@1265 99
Chris@1265 100 void isPeak_flat() {
Chris@1265 101 Column c { 0.0, 0.0, 0.0 };
Chris@1265 102 QVERIFY(C::isPeak(c, 0));
Chris@1265 103 QVERIFY(!C::isPeak(c, 1));
Chris@1265 104 QVERIFY(!C::isPeak(c, 2));
Chris@1265 105 }
Chris@1265 106
Chris@1265 107 void isPeak_mixedSign() {
Chris@1265 108 Column c { 0.4, -0.5, -0.3, -0.6, 0.1, -0.3 };
Chris@1265 109 QVERIFY(C::isPeak(c, 0));
Chris@1265 110 QVERIFY(!C::isPeak(c, 1));
Chris@1265 111 QVERIFY(C::isPeak(c, 2));
Chris@1265 112 QVERIFY(!C::isPeak(c, 3));
Chris@1265 113 QVERIFY(C::isPeak(c, 4));
Chris@1265 114 QVERIFY(!C::isPeak(c, 5));
Chris@1265 115 }
Chris@1265 116
Chris@1265 117 void isPeak_duplicate() {
Chris@1265 118 Column c({ 0.5, 0.5, 0.4, 0.4 });
Chris@1265 119 QVERIFY(C::isPeak(c, 0));
Chris@1265 120 QVERIFY(!C::isPeak(c, 1));
Chris@1265 121 QVERIFY(!C::isPeak(c, 2));
Chris@1265 122 QVERIFY(!C::isPeak(c, 3));
Chris@1265 123 c = { 0.4, 0.4, 0.5, 0.5 };
Chris@1265 124 QVERIFY(C::isPeak(c, 0)); // counterintuitive but necessary
Chris@1265 125 QVERIFY(!C::isPeak(c, 1));
Chris@1265 126 QVERIFY(C::isPeak(c, 2));
Chris@1265 127 QVERIFY(!C::isPeak(c, 3));
Chris@1265 128 }
Chris@1265 129
Chris@1265 130 void peakPick() {
Chris@1265 131 QCOMPARE(C::peakPick({}), Column());
Chris@1265 132 Column c({ 0.5, 0.5, 0.4, 0.4 });
Chris@1265 133 QCOMPARE(C::peakPick(c), Column({ 0.5, 0.0, 0.0, 0.0 }));
Chris@1265 134 c = Column({ 0.4, -0.5, -0.3, -0.6, 0.1, -0.3 });
Chris@1265 135 QCOMPARE(C::peakPick(c), Column({ 0.4, 0.0, -0.3, 0.0, 0.1, 0.0 }));
Chris@1265 136 }
Chris@1265 137
Chris@1265 138 void normalize_null() {
Chris@1265 139 QCOMPARE(C::normalize({}, ColumnNormalization::None), Column());
Chris@1265 140 QCOMPARE(C::normalize({}, ColumnNormalization::Sum1), Column());
Chris@1265 141 QCOMPARE(C::normalize({}, ColumnNormalization::Max1), Column());
Chris@1265 142 QCOMPARE(C::normalize({}, ColumnNormalization::Hybrid), Column());
Chris@1265 143 }
Chris@1265 144
Chris@1265 145 void normalize_none() {
Chris@1265 146 Column c { 1, 2, 3, 4 };
Chris@1265 147 QCOMPARE(C::normalize(c, ColumnNormalization::None), c);
Chris@1265 148 }
Chris@1265 149
Chris@1266 150 void normalize_none_mixedSign() {
Chris@1266 151 Column c { 1, 2, -3, -4 };
Chris@1266 152 QCOMPARE(C::normalize(c, ColumnNormalization::None), c);
Chris@1266 153 }
Chris@1266 154
Chris@1265 155 void normalize_sum1() {
Chris@1265 156 Column c { 1, 2, 4, 3 };
Chris@1265 157 QCOMPARE(C::normalize(c, ColumnNormalization::Sum1),
Chris@1265 158 Column({ 0.1, 0.2, 0.4, 0.3 }));
Chris@1265 159 }
Chris@1265 160
Chris@1266 161 void normalize_sum1_mixedSign() {
Chris@1266 162 Column c { 1, 2, -4, -3 };
Chris@1266 163 QCOMPARE(C::normalize(c, ColumnNormalization::Sum1),
Chris@1266 164 Column({ 0.1, 0.2, -0.4, -0.3 }));
Chris@1266 165 }
Chris@1266 166
Chris@1265 167 void normalize_max1() {
Chris@1265 168 Column c { 4, 3, 2, 1 };
Chris@1265 169 QCOMPARE(C::normalize(c, ColumnNormalization::Max1),
Chris@1265 170 Column({ 1.0, 0.75, 0.5, 0.25 }));
Chris@1265 171 }
Chris@1265 172
Chris@1266 173 void normalize_max1_mixedSign() {
Chris@1266 174 Column c { -4, -3, 2, 1 };
Chris@1266 175 QCOMPARE(C::normalize(c, ColumnNormalization::Max1),
Chris@1266 176 Column({ -1.0, -0.75, 0.5, 0.25 }));
Chris@1266 177 }
Chris@1266 178
Chris@1265 179 void normalize_hybrid() {
Chris@1265 180 // with max == 99, log10(max+1) == 2 so scale factor will be 2/99
Chris@1265 181 Column c { 22, 44, 99, 66 };
Chris@1265 182 QCOMPARE(C::normalize(c, ColumnNormalization::Hybrid),
Chris@1265 183 Column({ 44.0/99.0, 88.0/99.0, 2.0, 132.0/99.0 }));
Chris@1265 184 }
Chris@1265 185
Chris@1266 186 void normalize_hybrid_mixedSign() {
Chris@1266 187 // with max == 99, log10(max+1) == 2 so scale factor will be 2/99
Chris@1266 188 Column c { 22, 44, -99, -66 };
Chris@1266 189 QCOMPARE(C::normalize(c, ColumnNormalization::Hybrid),
Chris@1266 190 Column({ 44.0/99.0, 88.0/99.0, -2.0, -132.0/99.0 }));
Chris@1266 191 }
Chris@1266 192
Chris@1266 193 void distribute_simple() {
Chris@1266 194 Column in { 1, 2, 3 };
Chris@1266 195 BinMapping binfory { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5 };
Chris@1266 196 Column expected { 1, 1, 2, 2, 3, 3 };
Chris@1266 197 Column actual(C::distribute(in, 6, binfory, 0, false));
Chris@1266 198 report(actual);
Chris@1266 199 QCOMPARE(actual, expected);
Chris@1266 200 }
Chris@1266 201
Chris@1266 202 void distribute_simple_interpolated() {
Chris@1266 203 Column in { 1, 2, 3 };
Chris@1266 204 BinMapping binfory { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5 };
Chris@1267 205 // There is a 0.5-bin offset from the distribution you might
Chris@1267 206 // expect, because this corresponds visually to the way that
Chris@1267 207 // bin values are duplicated upwards in simple_distribution.
Chris@1267 208 // It means that switching between interpolated and
Chris@1267 209 // non-interpolated views retains the visual position of each
Chris@1267 210 // bin peak as somewhere in the middle of the scale area for
Chris@1267 211 // that bin.
Chris@1267 212 Column expected { 1, 1, 1.5, 2, 2.5, 3 };
Chris@1266 213 Column actual(C::distribute(in, 6, binfory, 0, true));
Chris@1266 214 report(actual);
Chris@1266 215 QCOMPARE(actual, expected);
Chris@1266 216 }
Chris@1266 217
Chris@1266 218 void distribute_nonlinear() {
Chris@1266 219 Column in { 1, 2, 3 };
Chris@1266 220 BinMapping binfory { 0.0, 0.2, 0.5, 1.0, 2.0, 2.5 };
Chris@1266 221 Column expected { 1, 1, 1, 2, 3, 3 };
Chris@1266 222 Column actual(C::distribute(in, 6, binfory, 0, false));
Chris@1266 223 report(actual);
Chris@1266 224 QCOMPARE(actual, expected);
Chris@1266 225 }
Chris@1266 226
Chris@1266 227 void distribute_nonlinear_interpolated() {
Chris@1267 228 // See distribute_simple_interpolated
Chris@1266 229 Column in { 1, 2, 3 };
Chris@1266 230 BinMapping binfory { 0.0, 0.2, 0.5, 1.0, 2.0, 2.5 };
Chris@1267 231 Column expected { 1, 1, 1, 1.5, 2.5, 3 };
Chris@1266 232 Column actual(C::distribute(in, 6, binfory, 0, true));
Chris@1266 233 report(actual);
Chris@1266 234 QCOMPARE(actual, expected);
Chris@1266 235 }
Chris@1266 236
Chris@1266 237 void distribute_shrinking() {
Chris@1266 238 Column in { 4, 1, 2, 3, 5, 6 };
Chris@1266 239 BinMapping binfory { 0.0, 2.0, 4.0 };
Chris@1266 240 Column expected { 4, 3, 6 };
Chris@1266 241 Column actual(C::distribute(in, 3, binfory, 0, false));
Chris@1266 242 report(actual);
Chris@1266 243 QCOMPARE(actual, expected);
Chris@1266 244 }
Chris@1266 245
Chris@1266 246 void distribute_shrinking_interpolated() {
Chris@1266 247 // should be same as distribute_shrinking, we don't
Chris@1266 248 // interpolate when resizing down
Chris@1266 249 Column in { 4, 1, 2, 3, 5, 6 };
Chris@1266 250 BinMapping binfory { 0.0, 2.0, 4.0 };
Chris@1266 251 Column expected { 4, 3, 6 };
Chris@1266 252 Column actual(C::distribute(in, 3, binfory, 0, true));
Chris@1266 253 report(actual);
Chris@1266 254 QCOMPARE(actual, expected);
Chris@1266 255 }
Chris@1265 256
Chris@1304 257 void distribute_nonlinear_someshrinking_interpolated() {
Chris@1304 258 // But we *should* interpolate if the mapping involves
Chris@1304 259 // shrinking some bins but expanding others. See
Chris@1304 260 // distribute_simple_interpolated for note on 0.5 offset
Chris@1304 261 Column in { 4, 1, 2, 3, 5, 6 };
Chris@1304 262 BinMapping binfory { 0.0, 3.0, 4.0, 4.5 };
Chris@1304 263 Column expected { 4.0, 2.5, 4.0, 5.0 };
Chris@1304 264 Column actual(C::distribute(in, 4, binfory, 0, true));
Chris@1304 265 report(actual);
Chris@1304 266 QCOMPARE(actual, expected);
Chris@1304 267 binfory = BinMapping { 0.5, 1.0, 2.0, 5.0 };
Chris@1304 268 expected = { 4.0, 2.5, 1.5, 5.5 };
Chris@1304 269 actual = (C::distribute(in, 4, binfory, 0, true));
Chris@1304 270 report(actual);
Chris@1304 271 QCOMPARE(actual, expected);
Chris@1304 272 }
Chris@1265 273 };
Chris@1265 274
Chris@1265 275 #endif
Chris@1265 276