changeset 1528:a7485c1bdba5

Tests and a couple of minor fixes for zoom constraints
author Chris Cannam
date Tue, 18 Sep 2018 15:04:46 +0100
parents 8988b27ebf38
children c1c45c5146bb b89705af7a60
files base/BaseTypes.h base/ZoomConstraint.h data/model/PowerOfSqrtTwoZoomConstraint.cpp data/model/PowerOfSqrtTwoZoomConstraint.h data/model/PowerOfTwoZoomConstraint.cpp data/model/PowerOfTwoZoomConstraint.h data/model/test/TestZoomConstraints.h data/model/test/files.pri data/model/test/svcore-data-model-test.cpp
diffstat 9 files changed, 235 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/base/BaseTypes.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/base/BaseTypes.h	Tue Sep 18 15:04:46 2018 +0100
@@ -12,8 +12,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef BASE_TYPES_H
-#define BASE_TYPES_H
+#ifndef SV_BASE_TYPES_H
+#define SV_BASE_TYPES_H
 
 #include <cstdint>
 #include <complex>
--- a/base/ZoomConstraint.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/base/ZoomConstraint.h	Tue Sep 18 15:04:46 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _ZOOM_CONSTRAINT_H_
-#define _ZOOM_CONSTRAINT_H_
+#ifndef SV_ZOOM_CONSTRAINT_H
+#define SV_ZOOM_CONSTRAINT_H
 
 #include <stdlib.h>
 
@@ -49,7 +49,7 @@
      * depending on the rounding direction supplied.
      */
     virtual int getNearestBlockSize(int requestedBlockSize,
-                                       RoundingDirection = RoundNearest)
+                                    RoundingDirection = RoundNearest)
         const
     {
         if (requestedBlockSize > getMaxZoomLevel()) return getMaxZoomLevel();
--- a/data/model/PowerOfSqrtTwoZoomConstraint.cpp	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfSqrtTwoZoomConstraint.cpp	Tue Sep 18 15:04:46 2018 +0100
@@ -18,6 +18,8 @@
 #include <iostream>
 #include <cmath>
 
+#include "base/Debug.h"
+
 
 int
 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(int blockSize,
@@ -34,7 +36,7 @@
                                                   int &power,
                                                   RoundingDirection dir) const
 {
-//    cerr << "given " << blockSize << endl;
+//    SVCERR << "given " << blockSize << endl;
 
     int minCachePower = getMinCachePower();
 
@@ -46,13 +48,18 @@
             prevVal = val;
             val *= sqrtf(2.f);
         }
-        int rval;
-        if (dir == RoundUp) rval = int(val + 0.01f);
-        else if (dir == RoundDown) rval = int(prevVal + 0.01f);
-        else if (val - float(blockSize) <
-                 float(blockSize) - prevVal) rval = int(val + 0.01f);
-        else rval = int(prevVal + 0.01);
-//        SVDEBUG << "returning " << rval << endl;
+        int rval = int(val + 0.01f);
+//        SVCERR << "got val = " << val << ", rval = " << rval << ", prevVal = " << prevVal << endl;
+        if (rval != blockSize && dir != RoundUp) {
+            if (dir == RoundDown) {
+                rval = int(prevVal + 0.01f);
+            } else if (val - float(blockSize) < float(blockSize) - prevVal) {
+                rval = int(val + 0.01f);
+            } else {
+                rval = int(prevVal + 0.01);
+            }
+        }
+//        SVCERR << "returning " << rval << endl;
         return rval;
     }
 
@@ -75,7 +82,7 @@
                     << (power - minCachePower));
         }
 
-//        SVDEBUG << "Testing base " << base << endl;
+//        SVCERR << "Testing base " << base << " (i = " << i << ", power = " << power << ", type = " << type << ")" << endl;
 
         if (base == blockSize) {
             result = base;
--- a/data/model/PowerOfSqrtTwoZoomConstraint.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfSqrtTwoZoomConstraint.h	Tue Sep 18 15:04:46 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _POWER_OF_SQRT_TWO_ZOOM_CONSTRAINT_H_
-#define _POWER_OF_SQRT_TWO_ZOOM_CONSTRAINT_H_
+#ifndef SV_POWER_OF_SQRT_TWO_ZOOM_CONSTRAINT_H
+#define SV_POWER_OF_SQRT_TWO_ZOOM_CONSTRAINT_H
 
 #include "base/ZoomConstraint.h"
 
@@ -22,13 +22,13 @@
 {
 public:
     virtual int getNearestBlockSize(int requestedBlockSize,
-                                       RoundingDirection dir = RoundNearest)
+                                    RoundingDirection dir = RoundNearest)
         const;
     
     virtual int getNearestBlockSize(int requestedBlockSize,
-                                       int &type,
-                                       int &power,
-                                       RoundingDirection dir = RoundNearest)
+                                    int &type,
+                                    int &power,
+                                    RoundingDirection dir = RoundNearest)
         const;
         
     virtual int getMinCachePower() const { return 6; }
--- a/data/model/PowerOfTwoZoomConstraint.cpp	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfTwoZoomConstraint.cpp	Tue Sep 18 15:04:46 2018 +0100
@@ -19,29 +19,32 @@
 PowerOfTwoZoomConstraint::getNearestBlockSize(int req,
                                               RoundingDirection dir) const
 {
-    int result = 0;
+    int max = getMaxZoomLevel();
 
-    for (int bs = 1; ; bs *= 2) {
-        if (bs >= req) {
+    if (req > max) {
+        return max;
+    }
+
+    for (int bs = 1; bs <= max; bs *= 2) {
+        if (bs < req) {
+            continue;
+        } else if (bs == req) {
+            return bs;
+        } else { // bs > req
             if (dir == RoundNearest) {
                 if (bs - req < req - bs/2) {
-                    result = bs;
-                    break;
+                    return bs;
                 } else {
-                    result = bs/2;
-                    break;
+                    return bs/2;
                 }
             } else if (dir == RoundDown) {
-                result = bs/2;
-                break;
+                return bs/2;
             } else {
-                result = bs;
-                break;
+                return bs;
             }
         }
     }
 
-    if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
-    return result;
+    return max;
 }
 
--- a/data/model/PowerOfTwoZoomConstraint.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfTwoZoomConstraint.h	Tue Sep 18 15:04:46 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _POWER_OF_TWO_ZOOM_CONSTRAINT_H_
-#define _POWER_OF_TWO_ZOOM_CONSTRAINT_H_
+#ifndef SV_POWER_OF_TWO_ZOOM_CONSTRAINT_H
+#define SV_POWER_OF_TWO_ZOOM_CONSTRAINT_H
 
 #include "base/ZoomConstraint.h"
 
@@ -22,7 +22,7 @@
 {
 public:
     virtual int getNearestBlockSize(int requestedBlockSize,
-                                       RoundingDirection dir = RoundNearest)
+                                    RoundingDirection dir = RoundNearest)
         const;
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/model/test/TestZoomConstraints.h	Tue Sep 18 15:04:46 2018 +0100
@@ -0,0 +1,180 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef TEST_ZOOM_CONSTRAINTS_H
+#define TEST_ZOOM_CONSTRAINTS_H
+
+#include "../PowerOfTwoZoomConstraint.h"
+#include "../PowerOfSqrtTwoZoomConstraint.h"
+
+#include <QObject>
+#include <QtTest>
+#include <QDir>
+
+#include <iostream>
+
+using namespace std;
+
+class TestZoomConstraints : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void unconstrainedNearest() {
+        ZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1), 1);
+        QCOMPARE(c.getNearestBlockSize(2), 2);
+        QCOMPARE(c.getNearestBlockSize(3), 3);
+        QCOMPARE(c.getNearestBlockSize(4), 4);
+        QCOMPARE(c.getNearestBlockSize(20), 20);
+        QCOMPARE(c.getNearestBlockSize(23), 23);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max), max);
+        QCOMPARE(c.getNearestBlockSize(max+1), max);
+    }
+    
+    void unconstrainedUp() {
+        ZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1, ZoomConstraint::RoundUp), 1);
+        QCOMPARE(c.getNearestBlockSize(2, ZoomConstraint::RoundUp), 2);
+        QCOMPARE(c.getNearestBlockSize(3, ZoomConstraint::RoundUp), 3);
+        QCOMPARE(c.getNearestBlockSize(4, ZoomConstraint::RoundUp), 4);
+        QCOMPARE(c.getNearestBlockSize(20, ZoomConstraint::RoundUp), 20);
+        QCOMPARE(c.getNearestBlockSize(32, ZoomConstraint::RoundUp), 32);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max, ZoomConstraint::RoundUp), max);
+        QCOMPARE(c.getNearestBlockSize(max+1, ZoomConstraint::RoundUp), max);
+    }
+    
+    void unconstrainedDown() {
+        ZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1, ZoomConstraint::RoundDown), 1);
+        QCOMPARE(c.getNearestBlockSize(2, ZoomConstraint::RoundDown), 2);
+        QCOMPARE(c.getNearestBlockSize(3, ZoomConstraint::RoundDown), 3);
+        QCOMPARE(c.getNearestBlockSize(4, ZoomConstraint::RoundDown), 4);
+        QCOMPARE(c.getNearestBlockSize(20, ZoomConstraint::RoundDown), 20);
+        QCOMPARE(c.getNearestBlockSize(32, ZoomConstraint::RoundDown), 32);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max, ZoomConstraint::RoundDown), max);
+        QCOMPARE(c.getNearestBlockSize(max+1, ZoomConstraint::RoundDown), max);
+    }
+
+    void powerOfTwoNearest() {
+        PowerOfTwoZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1), 1);
+        QCOMPARE(c.getNearestBlockSize(2), 2);
+        QCOMPARE(c.getNearestBlockSize(3), 2);
+        QCOMPARE(c.getNearestBlockSize(4), 4);
+        QCOMPARE(c.getNearestBlockSize(20), 16);
+        QCOMPARE(c.getNearestBlockSize(23), 16);
+        QCOMPARE(c.getNearestBlockSize(24), 16);
+        QCOMPARE(c.getNearestBlockSize(25), 32);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max), max);
+        QCOMPARE(c.getNearestBlockSize(max+1), max);
+    }
+    
+    void powerOfTwoUp() {
+        PowerOfTwoZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1, ZoomConstraint::RoundUp), 1);
+        QCOMPARE(c.getNearestBlockSize(2, ZoomConstraint::RoundUp), 2);
+        QCOMPARE(c.getNearestBlockSize(3, ZoomConstraint::RoundUp), 4);
+        QCOMPARE(c.getNearestBlockSize(4, ZoomConstraint::RoundUp), 4);
+        QCOMPARE(c.getNearestBlockSize(20, ZoomConstraint::RoundUp), 32);
+        QCOMPARE(c.getNearestBlockSize(32, ZoomConstraint::RoundUp), 32);
+        QCOMPARE(c.getNearestBlockSize(33, ZoomConstraint::RoundUp), 64);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max, ZoomConstraint::RoundUp), max);
+        QCOMPARE(c.getNearestBlockSize(max+1, ZoomConstraint::RoundUp), max);
+    }
+    
+    void powerOfTwoDown() {
+        PowerOfTwoZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1, ZoomConstraint::RoundDown), 1);
+        QCOMPARE(c.getNearestBlockSize(2, ZoomConstraint::RoundDown), 2);
+        QCOMPARE(c.getNearestBlockSize(3, ZoomConstraint::RoundDown), 2);
+        QCOMPARE(c.getNearestBlockSize(4, ZoomConstraint::RoundDown), 4);
+        QCOMPARE(c.getNearestBlockSize(20, ZoomConstraint::RoundDown), 16);
+        QCOMPARE(c.getNearestBlockSize(32, ZoomConstraint::RoundDown), 32);
+        QCOMPARE(c.getNearestBlockSize(33, ZoomConstraint::RoundDown), 32);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max, ZoomConstraint::RoundDown), max);
+        QCOMPARE(c.getNearestBlockSize(max+1, ZoomConstraint::RoundDown), max);
+    }
+
+    void powerOfSqrtTwoNearest() {
+        PowerOfSqrtTwoZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1), 1);
+        QCOMPARE(c.getNearestBlockSize(2), 2);
+        QCOMPARE(c.getNearestBlockSize(3), 2);
+        QCOMPARE(c.getNearestBlockSize(4), 4);
+        QCOMPARE(c.getNearestBlockSize(18), 16);
+        QCOMPARE(c.getNearestBlockSize(19), 16);
+        QCOMPARE(c.getNearestBlockSize(20), 22);
+        QCOMPARE(c.getNearestBlockSize(23), 22);
+        QCOMPARE(c.getNearestBlockSize(28), 32);
+        // PowerOfSqrtTwoZoomConstraint makes an effort to ensure
+        // bigger numbers get rounded to a multiple of something
+        // simple (64 or 90 depending on whether they are power-of-two
+        // or power-of-sqrt-two types)
+        QCOMPARE(c.getNearestBlockSize(800), 720);
+        QCOMPARE(c.getNearestBlockSize(1023), 1024);
+        QCOMPARE(c.getNearestBlockSize(1024), 1024);
+        QCOMPARE(c.getNearestBlockSize(1025), 1024);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max), max);
+        QCOMPARE(c.getNearestBlockSize(max+1), max);
+    }
+    
+    void powerOfSqrtTwoUp() {
+        PowerOfSqrtTwoZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1, ZoomConstraint::RoundUp), 1);
+        QCOMPARE(c.getNearestBlockSize(2, ZoomConstraint::RoundUp), 2);
+        QCOMPARE(c.getNearestBlockSize(3, ZoomConstraint::RoundUp), 4);
+        QCOMPARE(c.getNearestBlockSize(4, ZoomConstraint::RoundUp), 4);
+        QCOMPARE(c.getNearestBlockSize(18, ZoomConstraint::RoundUp), 22);
+        QCOMPARE(c.getNearestBlockSize(22, ZoomConstraint::RoundUp), 22);
+        QCOMPARE(c.getNearestBlockSize(23, ZoomConstraint::RoundUp), 32);
+        QCOMPARE(c.getNearestBlockSize(800, ZoomConstraint::RoundUp), 1024);
+        QCOMPARE(c.getNearestBlockSize(1023, ZoomConstraint::RoundUp), 1024);
+        QCOMPARE(c.getNearestBlockSize(1024, ZoomConstraint::RoundUp), 1024);
+        // see comment above
+        QCOMPARE(c.getNearestBlockSize(1025, ZoomConstraint::RoundUp), 1440);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max, ZoomConstraint::RoundUp), max);
+        QCOMPARE(c.getNearestBlockSize(max+1, ZoomConstraint::RoundUp), max);
+    }
+    
+    void powerOfSqrtTwoDown() {
+        PowerOfSqrtTwoZoomConstraint c;
+        QCOMPARE(c.getNearestBlockSize(1, ZoomConstraint::RoundDown), 1);
+        QCOMPARE(c.getNearestBlockSize(2, ZoomConstraint::RoundDown), 2);
+        QCOMPARE(c.getNearestBlockSize(3, ZoomConstraint::RoundDown), 2);
+        QCOMPARE(c.getNearestBlockSize(4, ZoomConstraint::RoundDown), 4);
+        QCOMPARE(c.getNearestBlockSize(18, ZoomConstraint::RoundDown), 16);
+        QCOMPARE(c.getNearestBlockSize(22, ZoomConstraint::RoundDown), 22);
+        QCOMPARE(c.getNearestBlockSize(23, ZoomConstraint::RoundDown), 22);
+        // see comment above
+        QCOMPARE(c.getNearestBlockSize(800, ZoomConstraint::RoundDown), 720);
+        QCOMPARE(c.getNearestBlockSize(1023, ZoomConstraint::RoundDown), 720);
+        QCOMPARE(c.getNearestBlockSize(1024, ZoomConstraint::RoundDown), 1024);
+        QCOMPARE(c.getNearestBlockSize(1025, ZoomConstraint::RoundDown), 1024);
+        int max = c.getMaxZoomLevel();
+        QCOMPARE(c.getNearestBlockSize(max, ZoomConstraint::RoundDown), max);
+        QCOMPARE(c.getNearestBlockSize(max+1, ZoomConstraint::RoundDown), max);
+    }
+};
+
+#endif
+    
--- a/data/model/test/files.pri	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/test/files.pri	Tue Sep 18 15:04:46 2018 +0100
@@ -1,7 +1,8 @@
 TEST_HEADERS += \
 	Compares.h \
 	MockWaveModel.h \
-	TestFFTModel.h
+	TestFFTModel.h \
+        TestZoomConstraints.h
 	
 TEST_SOURCES += \
 	MockWaveModel.cpp \
--- a/data/model/test/svcore-data-model-test.cpp	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/test/svcore-data-model-test.cpp	Tue Sep 18 15:04:46 2018 +0100
@@ -12,6 +12,7 @@
 */
 
 #include "TestFFTModel.h"
+#include "TestZoomConstraints.h"
 
 #include <QtTest>
 
@@ -33,6 +34,12 @@
         else ++bad;
     }
 
+    {
+        TestZoomConstraints t;
+        if (QTest::qExec(&t, argc, argv) == 0) ++good;
+        else ++bad;
+    }
+
     if (bad > 0) {
         SVCERR << "\n********* " << bad << " test suite(s) failed!\n" << endl;
         return 1;