Chris@1392: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@1392: 
Chris@1392: /*
Chris@1392:     Sonic Visualiser
Chris@1392:     An audio file viewer and annotation editor.
Chris@1392:     Centre for Digital Music, Queen Mary, University of London.
Chris@1392:     
Chris@1392:     This program is free software; you can redistribute it and/or
Chris@1392:     modify it under the terms of the GNU General Public License as
Chris@1392:     published by the Free Software Foundation; either version 2 of the
Chris@1392:     License, or (at your option) any later version.  See the file
Chris@1392:     COPYING included with this distribution for more information.
Chris@1392: */
Chris@1392: 
Chris@1392: #ifndef TEST_LOG_RANGE_H
Chris@1392: #define TEST_LOG_RANGE_H
Chris@1392: 
Chris@1392: #include "../LogRange.h"
Chris@1392: 
Chris@1392: #include <QObject>
Chris@1392: #include <QtTest>
Chris@1392: 
Chris@1392: #include <iostream>
Chris@1392: #include <cmath>
Chris@1392: 
Chris@1392: using namespace std;
Chris@1392: 
Chris@1392: class TestLogRange : public QObject
Chris@1392: {
Chris@1392:     Q_OBJECT
Chris@1392: 
Chris@1392: private slots:
Chris@1392: 
Chris@1392:     void mapPositiveAboveDefaultThreshold()
Chris@1392:     {
Chris@1392:         QCOMPARE(LogRange::map(10.0), 1.0);
Chris@1392:         QCOMPARE(LogRange::map(100.0), 2.0);
Chris@1392:         QCOMPARE(LogRange::map(0.1), -1.0);
Chris@1392:         QCOMPARE(LogRange::map(1.0), 0.0);
Chris@1392:         QCOMPARE(LogRange::map(0.0000001), -7.0);
Chris@1392:         QCOMPARE(LogRange::map(20.0), log10(20.0));
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapPositiveAboveSetThreshold()
Chris@1392:     {
Chris@1392:         QCOMPARE(LogRange::map(10.0, -10.0), 1.0);
Chris@1392:         QCOMPARE(LogRange::map(100.0, 1.0), 2.0);
Chris@1392:         QCOMPARE(LogRange::map(0.1, -5.0), -1.0);
Chris@1392:         QCOMPARE(LogRange::map(1.0, -0.01), 0.0);
Chris@1392:         QCOMPARE(LogRange::map(0.0000001, -20.0), -7.0);
Chris@1392:         QCOMPARE(LogRange::map(20.0, 0.0), log10(20.0));
Chris@1392:     }
Chris@1392: 
Chris@1392:     void mapZeroDefaultThreshold()
Chris@1392:     {
Chris@1392:         QCOMPARE(LogRange::map(0.0), -10.0);
Chris@1392:     }
Chris@1392: 
Chris@1392:     void mapZeroSetThreshold()
Chris@1392:     {
Chris@1392:         QCOMPARE(LogRange::map(0.0, 12.0), 12.0);
Chris@1392:         QCOMPARE(LogRange::map(0.0, -12.0), -12.0);
Chris@1392:         QCOMPARE(LogRange::map(0.0, 0.0), 0.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapPositiveBelowDefaultThreshold()
Chris@1392:     {
Chris@1392:         // The threshold is used only for zero values, not for very
Chris@1392:         // small ones -- it's arguably a stand-in or replacement value
Chris@1392:         // rather than a threshold. So this should behave the same as
Chris@1392:         // for values above the threshold.
Chris@1392:         QCOMPARE(LogRange::map(1e-10), -10.0);
Chris@1392:         QCOMPARE(LogRange::map(1e-20), -20.0);
Chris@1392:         QCOMPARE(LogRange::map(1e-100), -100.0);
Chris@1392:     }
Chris@1392: 
Chris@1392:     void mapPositiveBelowSetThreshold()
Chris@1392:     {
Chris@1392:         // As above
Chris@1392:         QCOMPARE(LogRange::map(10.0, 4.0), 1.0);
Chris@1392:         QCOMPARE(LogRange::map(1e-10, 4.0), -10.0);
Chris@1392:         QCOMPARE(LogRange::map(1e-20, -15.0), -20.0);
Chris@1392:         QCOMPARE(LogRange::map(1e-100, -100.0), -100.0);
Chris@1392:     }
Chris@1392: 
Chris@1392:     void mapNegative()
Chris@1392:     {
Chris@1392:         // Should always return map of absolute value. These are
Chris@1392:         // picked from vaarious of the above tests.
Chris@1392:         
Chris@1392:         QCOMPARE(LogRange::map(-10.0), 1.0);
Chris@1392:         QCOMPARE(LogRange::map(-100.0), 2.0);
Chris@1392:         QCOMPARE(LogRange::map(-0.1), -1.0);
Chris@1392:         QCOMPARE(LogRange::map(-1.0), 0.0);
Chris@1392:         QCOMPARE(LogRange::map(-0.0000001), -7.0);
Chris@1392:         QCOMPARE(LogRange::map(-20.0), log10(20.0));
Chris@1392:         QCOMPARE(LogRange::map(-10.0, 4.0), 1.0);
Chris@1392:         QCOMPARE(LogRange::map(-1e-10, 4.0), -10.0);
Chris@1392:         QCOMPARE(LogRange::map(-1e-20, -15.0), -20.0);
Chris@1392:         QCOMPARE(LogRange::map(-1e-100, -100.0), -100.0);
Chris@1392:         QCOMPARE(LogRange::map(-0.0, 12.0), 12.0);
Chris@1392:         QCOMPARE(LogRange::map(-0.0, -12.0), -12.0);
Chris@1392:         QCOMPARE(LogRange::map(-0.0, 0.0), 0.0);
Chris@1392:     }
Chris@1392: 
Chris@1392:     void unmap()
Chris@1392:     {
Chris@1392:         // Simply pow(10, x)
Chris@1392: 
Chris@1392:         QCOMPARE(LogRange::unmap(0.0), 1.0);
Chris@1392:         QCOMPARE(LogRange::unmap(1.0), 10.0);
Chris@1392:         QCOMPARE(LogRange::unmap(-1.0), 0.1);
Chris@1392:         QCOMPARE(LogRange::unmap(100.0), 1e+100);
Chris@1392:         QCOMPARE(LogRange::unmap(-100.0), 1e-100);
Chris@1392:     }
Chris@1392: 
Chris@1392:     void mapRangeAllPositiveDefaultThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = 1.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = 10.0; max = 1.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if equal, the function uses an arbitrary 1.0 range before mapping
Chris@1392:         min = 10.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, 1.0); QCOMPARE(max, log10(11.0));
Chris@1392:     }
Chris@1392: 
Chris@1392:     void mapRangeAllPositiveSetThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = 1.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = 10.0; max = 1.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if equal, the function uses an arbitrary 1.0 range before mapping
Chris@1392:         min = 10.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, 1.0); QCOMPARE(max, log10(11.0));
Chris@1392:     }
Chris@1392: 
Chris@1392:     void mapRangeAllNegativeDefaultThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = -1.0; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -10.0; max = -1.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if equal, the function uses an arbitrary 1.0 range before mapping
Chris@1392:         min = -10.0; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, log10(9.0)); QCOMPARE(max, 1.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapRangeAllNegativeSetThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = -1.0; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -10.0; max = -1.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, 0.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if equal, the function uses an arbitrary 1.0 range before mapping
Chris@1392:         min = -10.0; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, log10(9.0)); QCOMPARE(max, 1.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapRangeAllNonNegativeDefaultThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = 0.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = 10.0; max = 0.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if equal, the function uses an arbitrary 1.0 range before mapping
Chris@1392:         min = 0.0; max = 0.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 0.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapRangeAllNonNegativeSetThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = 0.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = 10.0; max = 0.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if equal, the function uses an arbitrary 1.0 range before mapping
Chris@1392:         min = 0.0; max = 0.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 0.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapRangeAllNonPositiveDefaultThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = 0.0; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -10.0; max = 0.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapRangeAllNonPositiveSetThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = 0.0; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -10.0; max = 0.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapRangeSpanningZeroDefaultThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = -1.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -100.0; max = 1.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 2.0);
Chris@1392: 
Chris@1392:         min = -10.0; max = 1e-200;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = 1e-200; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -1e-200; max = 100.0;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 2.0);
Chris@1392: 
Chris@1392:         min = 10.0; max = -1e-200;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -10.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if none of the input range is above the threshold in
Chris@1392:         // magnitude, but it still spans zero, we use the input max as
Chris@1392:         // threshold and then add 1 for range
Chris@1392:         min = -1e-200; max = 1e-300;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -201.0); QCOMPARE(max, -200.0);
Chris@1392: 
Chris@1392:         min = 1e-200; max = -1e-300;
Chris@1392:         LogRange::mapRange(min, max);
Chris@1392:         QCOMPARE(min, -201.0); QCOMPARE(max, -200.0);
Chris@1392:     }
Chris@1392:     
Chris@1392:     void mapRangeSpanningZeroSetThreshold()
Chris@1392:     {
Chris@1392:         double min, max;
Chris@1392: 
Chris@1392:         min = -1.0; max = 10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -100.0; max = 1.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 2.0);
Chris@1392: 
Chris@1392:         min = -10.0; max = 1e-200;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = 1e-200; max = -10.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         min = -1e-200; max = 100.0;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 2.0);
Chris@1392: 
Chris@1392:         min = 10.0; max = -1e-200;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -4.0); QCOMPARE(max, 1.0);
Chris@1392: 
Chris@1392:         // if none of the input range is above the threshold in
Chris@1392:         // magnitude, but it still spans zero, we use the input max as
Chris@1392:         // threshold and then add 1 for range
Chris@1392:         min = -1e-200; max = 1e-300;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -201.0); QCOMPARE(max, -200.0);
Chris@1392: 
Chris@1392:         min = 1e-200; max = -1e-300;
Chris@1392:         LogRange::mapRange(min, max, -4.0);
Chris@1392:         QCOMPARE(min, -201.0); QCOMPARE(max, -200.0);
Chris@1392:     }
Chris@1392:     
Chris@1392: };
Chris@1392: 
Chris@1392: #endif