annotate base/test/TestColumnOp.h @ 1288:5ef9b4d4bbdb 3.0-integration

Filter out Xing/LAME info frames, rather than letting them go to the mp3 decoder as if they were audio frames. Fixes the 1152-sample zero pad at start of some decoded mp3 files (distinct from decoder delay). The logic here is based on the madplay code.
author Chris Cannam
date Thu, 24 Nov 2016 13:32:04 +0000
parents f50c0bbe9096
children 7cff8367d9b1
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@1265 26 using namespace std;
Chris@1265 27
Chris@1265 28 class TestColumnOp : public QObject
Chris@1265 29 {
Chris@1265 30 Q_OBJECT
Chris@1265 31
Chris@1265 32 typedef ColumnOp C;
Chris@1265 33 typedef ColumnOp::Column Column;
Chris@1266 34 typedef vector<double> BinMapping;
Chris@1266 35
Chris@1269 36 #ifdef REPORT
Chris@1266 37 template <typename T>
Chris@1266 38 void report(vector<T> v) {
Chris@1266 39 cerr << "Vector is: [ ";
Chris@1266 40 for (int i = 0; i < int(v.size()); ++i) {
Chris@1266 41 if (i > 0) cerr << ", ";
Chris@1266 42 cerr << v[i];
Chris@1266 43 }
Chris@1266 44 cerr << " ]\n";
Chris@1266 45 }
Chris@1269 46 #else
Chris@1269 47 template <typename T>
Chris@1269 48 void report(vector<T> ) { }
Chris@1269 49 #endif
Chris@1266 50
Chris@1265 51 private slots:
Chris@1265 52 void applyGain() {
Chris@1265 53 QCOMPARE(C::applyGain({}, 1.0), Column());
Chris@1265 54 Column c { 1, 2, 3, -4, 5, 6 };
Chris@1265 55 Column actual(C::applyGain(c, 1.5));
Chris@1265 56 Column expected { 1.5, 3, 4.5, -6, 7.5, 9 };
Chris@1265 57 QCOMPARE(actual, expected);
Chris@1265 58 actual = C::applyGain(c, 1.0);
Chris@1265 59 QCOMPARE(actual, c);
Chris@1265 60 actual = C::applyGain(c, 0.0);
Chris@1265 61 expected = { 0, 0, 0, 0, 0, 0 };
Chris@1265 62 QCOMPARE(actual, expected);
Chris@1265 63 }
Chris@1265 64
Chris@1265 65 void fftScale() {
Chris@1265 66 QCOMPARE(C::fftScale({}, 2.0), Column());
Chris@1265 67 Column c { 1, 2, 3, -4, 5 };
Chris@1265 68 Column actual(C::fftScale(c, 8));
Chris@1265 69 Column expected { 0.25, 0.5, 0.75, -1, 1.25 };
Chris@1265 70 QCOMPARE(actual, expected);
Chris@1265 71 }
Chris@1265 72
Chris@1265 73 void isPeak_null() {
Chris@1265 74 QVERIFY(!C::isPeak({}, 0));
Chris@1265 75 QVERIFY(!C::isPeak({}, 1));
Chris@1265 76 QVERIFY(!C::isPeak({}, -1));
Chris@1265 77 }
Chris@1265 78
Chris@1265 79 void isPeak_obvious() {
Chris@1265 80 Column c { 0.4, 0.5, 0.3 };
Chris@1265 81 QVERIFY(!C::isPeak(c, 0));
Chris@1265 82 QVERIFY(C::isPeak(c, 1));
Chris@1265 83 QVERIFY(!C::isPeak(c, 2));
Chris@1265 84 }
Chris@1265 85
Chris@1265 86 void isPeak_edges() {
Chris@1265 87 Column c { 0.5, 0.4, 0.3 };
Chris@1265 88 QVERIFY(C::isPeak(c, 0));
Chris@1265 89 QVERIFY(!C::isPeak(c, 1));
Chris@1265 90 QVERIFY(!C::isPeak(c, 2));
Chris@1265 91 QVERIFY(!C::isPeak(c, 3));
Chris@1265 92 QVERIFY(!C::isPeak(c, -1));
Chris@1265 93 c = { 1.4, 1.5 };
Chris@1265 94 QVERIFY(!C::isPeak(c, 0));
Chris@1265 95 QVERIFY(C::isPeak(c, 1));
Chris@1265 96 }
Chris@1265 97
Chris@1265 98 void isPeak_flat() {
Chris@1265 99 Column c { 0.0, 0.0, 0.0 };
Chris@1265 100 QVERIFY(C::isPeak(c, 0));
Chris@1265 101 QVERIFY(!C::isPeak(c, 1));
Chris@1265 102 QVERIFY(!C::isPeak(c, 2));
Chris@1265 103 }
Chris@1265 104
Chris@1265 105 void isPeak_mixedSign() {
Chris@1265 106 Column c { 0.4, -0.5, -0.3, -0.6, 0.1, -0.3 };
Chris@1265 107 QVERIFY(C::isPeak(c, 0));
Chris@1265 108 QVERIFY(!C::isPeak(c, 1));
Chris@1265 109 QVERIFY(C::isPeak(c, 2));
Chris@1265 110 QVERIFY(!C::isPeak(c, 3));
Chris@1265 111 QVERIFY(C::isPeak(c, 4));
Chris@1265 112 QVERIFY(!C::isPeak(c, 5));
Chris@1265 113 }
Chris@1265 114
Chris@1265 115 void isPeak_duplicate() {
Chris@1265 116 Column c({ 0.5, 0.5, 0.4, 0.4 });
Chris@1265 117 QVERIFY(C::isPeak(c, 0));
Chris@1265 118 QVERIFY(!C::isPeak(c, 1));
Chris@1265 119 QVERIFY(!C::isPeak(c, 2));
Chris@1265 120 QVERIFY(!C::isPeak(c, 3));
Chris@1265 121 c = { 0.4, 0.4, 0.5, 0.5 };
Chris@1265 122 QVERIFY(C::isPeak(c, 0)); // counterintuitive but necessary
Chris@1265 123 QVERIFY(!C::isPeak(c, 1));
Chris@1265 124 QVERIFY(C::isPeak(c, 2));
Chris@1265 125 QVERIFY(!C::isPeak(c, 3));
Chris@1265 126 }
Chris@1265 127
Chris@1265 128 void peakPick() {
Chris@1265 129 QCOMPARE(C::peakPick({}), Column());
Chris@1265 130 Column c({ 0.5, 0.5, 0.4, 0.4 });
Chris@1265 131 QCOMPARE(C::peakPick(c), Column({ 0.5, 0.0, 0.0, 0.0 }));
Chris@1265 132 c = Column({ 0.4, -0.5, -0.3, -0.6, 0.1, -0.3 });
Chris@1265 133 QCOMPARE(C::peakPick(c), Column({ 0.4, 0.0, -0.3, 0.0, 0.1, 0.0 }));
Chris@1265 134 }
Chris@1265 135
Chris@1265 136 void normalize_null() {
Chris@1265 137 QCOMPARE(C::normalize({}, ColumnNormalization::None), Column());
Chris@1265 138 QCOMPARE(C::normalize({}, ColumnNormalization::Sum1), Column());
Chris@1265 139 QCOMPARE(C::normalize({}, ColumnNormalization::Max1), Column());
Chris@1265 140 QCOMPARE(C::normalize({}, ColumnNormalization::Hybrid), Column());
Chris@1265 141 }
Chris@1265 142
Chris@1265 143 void normalize_none() {
Chris@1265 144 Column c { 1, 2, 3, 4 };
Chris@1265 145 QCOMPARE(C::normalize(c, ColumnNormalization::None), c);
Chris@1265 146 }
Chris@1265 147
Chris@1266 148 void normalize_none_mixedSign() {
Chris@1266 149 Column c { 1, 2, -3, -4 };
Chris@1266 150 QCOMPARE(C::normalize(c, ColumnNormalization::None), c);
Chris@1266 151 }
Chris@1266 152
Chris@1265 153 void normalize_sum1() {
Chris@1265 154 Column c { 1, 2, 4, 3 };
Chris@1265 155 QCOMPARE(C::normalize(c, ColumnNormalization::Sum1),
Chris@1265 156 Column({ 0.1, 0.2, 0.4, 0.3 }));
Chris@1265 157 }
Chris@1265 158
Chris@1266 159 void normalize_sum1_mixedSign() {
Chris@1266 160 Column c { 1, 2, -4, -3 };
Chris@1266 161 QCOMPARE(C::normalize(c, ColumnNormalization::Sum1),
Chris@1266 162 Column({ 0.1, 0.2, -0.4, -0.3 }));
Chris@1266 163 }
Chris@1266 164
Chris@1265 165 void normalize_max1() {
Chris@1265 166 Column c { 4, 3, 2, 1 };
Chris@1265 167 QCOMPARE(C::normalize(c, ColumnNormalization::Max1),
Chris@1265 168 Column({ 1.0, 0.75, 0.5, 0.25 }));
Chris@1265 169 }
Chris@1265 170
Chris@1266 171 void normalize_max1_mixedSign() {
Chris@1266 172 Column c { -4, -3, 2, 1 };
Chris@1266 173 QCOMPARE(C::normalize(c, ColumnNormalization::Max1),
Chris@1266 174 Column({ -1.0, -0.75, 0.5, 0.25 }));
Chris@1266 175 }
Chris@1266 176
Chris@1265 177 void normalize_hybrid() {
Chris@1265 178 // with max == 99, log10(max+1) == 2 so scale factor will be 2/99
Chris@1265 179 Column c { 22, 44, 99, 66 };
Chris@1265 180 QCOMPARE(C::normalize(c, ColumnNormalization::Hybrid),
Chris@1265 181 Column({ 44.0/99.0, 88.0/99.0, 2.0, 132.0/99.0 }));
Chris@1265 182 }
Chris@1265 183
Chris@1266 184 void normalize_hybrid_mixedSign() {
Chris@1266 185 // with max == 99, log10(max+1) == 2 so scale factor will be 2/99
Chris@1266 186 Column c { 22, 44, -99, -66 };
Chris@1266 187 QCOMPARE(C::normalize(c, ColumnNormalization::Hybrid),
Chris@1266 188 Column({ 44.0/99.0, 88.0/99.0, -2.0, -132.0/99.0 }));
Chris@1266 189 }
Chris@1266 190
Chris@1266 191 void distribute_simple() {
Chris@1266 192 Column in { 1, 2, 3 };
Chris@1266 193 BinMapping binfory { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5 };
Chris@1266 194 Column expected { 1, 1, 2, 2, 3, 3 };
Chris@1266 195 Column actual(C::distribute(in, 6, binfory, 0, false));
Chris@1266 196 report(actual);
Chris@1266 197 QCOMPARE(actual, expected);
Chris@1266 198 }
Chris@1266 199
Chris@1266 200 void distribute_simple_interpolated() {
Chris@1266 201 Column in { 1, 2, 3 };
Chris@1266 202 BinMapping binfory { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5 };
Chris@1267 203 // There is a 0.5-bin offset from the distribution you might
Chris@1267 204 // expect, because this corresponds visually to the way that
Chris@1267 205 // bin values are duplicated upwards in simple_distribution.
Chris@1267 206 // It means that switching between interpolated and
Chris@1267 207 // non-interpolated views retains the visual position of each
Chris@1267 208 // bin peak as somewhere in the middle of the scale area for
Chris@1267 209 // that bin.
Chris@1267 210 Column expected { 1, 1, 1.5, 2, 2.5, 3 };
Chris@1266 211 Column actual(C::distribute(in, 6, binfory, 0, true));
Chris@1266 212 report(actual);
Chris@1266 213 QCOMPARE(actual, expected);
Chris@1266 214 }
Chris@1266 215
Chris@1266 216 void distribute_nonlinear() {
Chris@1266 217 Column in { 1, 2, 3 };
Chris@1266 218 BinMapping binfory { 0.0, 0.2, 0.5, 1.0, 2.0, 2.5 };
Chris@1266 219 Column expected { 1, 1, 1, 2, 3, 3 };
Chris@1266 220 Column actual(C::distribute(in, 6, binfory, 0, false));
Chris@1266 221 report(actual);
Chris@1266 222 QCOMPARE(actual, expected);
Chris@1266 223 }
Chris@1266 224
Chris@1266 225 void distribute_nonlinear_interpolated() {
Chris@1267 226 // See distribute_simple_interpolated
Chris@1266 227 Column in { 1, 2, 3 };
Chris@1266 228 BinMapping binfory { 0.0, 0.2, 0.5, 1.0, 2.0, 2.5 };
Chris@1267 229 Column expected { 1, 1, 1, 1.5, 2.5, 3 };
Chris@1266 230 Column actual(C::distribute(in, 6, binfory, 0, true));
Chris@1266 231 report(actual);
Chris@1266 232 QCOMPARE(actual, expected);
Chris@1266 233 }
Chris@1266 234
Chris@1266 235 void distribute_shrinking() {
Chris@1266 236 Column in { 4, 1, 2, 3, 5, 6 };
Chris@1266 237 BinMapping binfory { 0.0, 2.0, 4.0 };
Chris@1266 238 Column expected { 4, 3, 6 };
Chris@1266 239 Column actual(C::distribute(in, 3, binfory, 0, false));
Chris@1266 240 report(actual);
Chris@1266 241 QCOMPARE(actual, expected);
Chris@1266 242 }
Chris@1266 243
Chris@1266 244 void distribute_shrinking_interpolated() {
Chris@1266 245 // should be same as distribute_shrinking, we don't
Chris@1266 246 // interpolate when resizing down
Chris@1266 247 Column in { 4, 1, 2, 3, 5, 6 };
Chris@1266 248 BinMapping binfory { 0.0, 2.0, 4.0 };
Chris@1266 249 Column expected { 4, 3, 6 };
Chris@1266 250 Column actual(C::distribute(in, 3, binfory, 0, true));
Chris@1266 251 report(actual);
Chris@1266 252 QCOMPARE(actual, expected);
Chris@1266 253 }
Chris@1265 254
Chris@1265 255
Chris@1265 256 };
Chris@1265 257
Chris@1265 258 #endif
Chris@1265 259