changeset 1527:710e6250a401 zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:14 +0100
parents d4a28d1479a8 (diff) 8988b27ebf38 (current diff)
children c1c45c5146bb
files base/BaseTypes.h base/ZoomConstraint.h data/fileio/QuickTimeFileReader.cpp data/fileio/QuickTimeFileReader.h data/fileio/test/testfiles/aac/32000-1.m4a data/fileio/test/testfiles/aac/44100-2.m4a data/fileio/test/testfiles/aiff/12000-6-16.aiff data/fileio/test/testfiles/aiff/48000-1-24.aiff data/fileio/test/testfiles/apple_lossless/32000-1.m4a data/fileio/test/testfiles/apple_lossless/44100-2.m4a data/fileio/test/testfiles/flac/44100-2.flac data/fileio/test/testfiles/mp3/32000-1.mp3 data/fileio/test/testfiles/mp3/44100-2.mp3 data/fileio/test/testfiles/ogg/32000-1.ogg data/fileio/test/testfiles/ogg/44100-2.ogg data/fileio/test/testfiles/wav/32000-1-16.wav data/fileio/test/testfiles/wav/44100-1-32.wav data/fileio/test/testfiles/wav/44100-2-16.wav data/fileio/test/testfiles/wav/44100-2-8.wav data/fileio/test/testfiles/wav/48000-1-16.wav data/fileio/test/testfiles/wav/8000-1-8.wav data/fileio/test/testfiles/wav/8000-2-16.wav data/fileio/test/testfiles/wav/8000-6-16.wav data/midi/rtmidi/RtError.h data/model/PowerOfSqrtTwoZoomConstraint.cpp data/model/PowerOfSqrtTwoZoomConstraint.h data/model/PowerOfTwoZoomConstraint.cpp data/model/PowerOfTwoZoomConstraint.h data/model/ReadOnlyWaveFileModel.cpp
diffstat 7 files changed, 148 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/base/BaseTypes.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/base/BaseTypes.h	Mon Sep 17 13:51:14 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>
@@ -55,5 +55,56 @@
 typedef std::vector<std::complex<float>,
                     breakfastquay::StlAllocator<std::complex<float>>> complexvec_t;
 
+/** Display zoom level. Can be an integer number of samples per pixel,
+ *  or an integer number of pixels per sample.
+ */
+struct ZoomLevel {
+
+    enum Zone {
+        FramesPerPixel, // zoomed out (as in classic SV)
+        PixelsPerFrame  // zoomed in beyond 1-1 (interpolating the waveform)
+    };
+    Zone zone;
+    int level;
+
+    bool operator<(const ZoomLevel &other) const {
+        if (zone == FramesPerPixel) {
+            if (other.zone == zone) {
+                return level < other.level;
+            } else {
+                return false;
+            }
+        } else {
+            if (other.zone == zone) {
+                return level > other.level;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    ZoomLevel incremented() const {
+        if (zone == FramesPerPixel) {
+            return { zone, level + 1 };
+        } else if (level == 1) {
+            return { FramesPerPixel, 2 };
+        } else if (level == 2) {
+            return { FramesPerPixel, 1 };
+        } else {
+            return { zone, level - 1 };
+        }
+    }
+
+    ZoomLevel decremented() const {
+        if (zone == PixelsPerFrame) {
+            return { zone, level + 1 };
+        } else if (level == 1) {
+            return { PixelsPerFrame, 2 };
+        } else {
+            return { zone, level - 1 };
+        }
+    }
+};
+
 #endif
 
--- a/base/ZoomConstraint.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/base/ZoomConstraint.h	Mon Sep 17 13:51:14 2018 +0100
@@ -13,11 +13,13 @@
     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>
 
+#include "BaseTypes.h"
+
 /**
  * ZoomConstraint is a simple interface that describes a limitation on
  * the available zoom sizes for a view, for example based on cache
@@ -39,30 +41,42 @@
     };
 
     /**
-     * Given the "ideal" block size (frames per pixel) for a given
-     * zoom level, return the nearest viable block size for this
-     * constraint.
+     * Given an "ideal" zoom level (frames per pixel or pixels per
+     * frame) for a given zoom level, return the nearest viable block
+     * size for this constraint.
      *
      * For example, if a block size of 1523 frames per pixel is
      * requested but the underlying model only supports value
      * summaries at powers-of-two block sizes, return 1024 or 2048
      * depending on the rounding direction supplied.
      */
-    virtual int getNearestBlockSize(int requestedBlockSize,
-                                       RoundingDirection = RoundNearest)
+    virtual ZoomLevel getNearestZoomLevel(ZoomLevel requestedZoomLevel,
+                                          RoundingDirection = RoundNearest)
         const
     {
-        if (requestedBlockSize > getMaxZoomLevel()) return getMaxZoomLevel();
-        else return requestedBlockSize;
+        if (getMaxZoomLevel() < requestedZoomLevel) return getMaxZoomLevel();
+	else return requestedZoomLevel;
     }
 
     /**
+     * Return the minimum zoom level within range for this constraint.
+     * Individual views will probably want to limit this, for example
+     * in order to ensure that at least one or two samples fit in the
+     * current window size, or in order to save on interpolation cost.
+     */
+    virtual ZoomLevel getMinZoomLevel() const {
+        return { ZoomLevel::PixelsPerFrame, 16384 };
+    }
+    
+    /**
      * Return the maximum zoom level within range for this constraint.
      * This is quite large -- individual views will probably want to
      * limit how far a user might reasonably zoom out based on other
      * factors such as the duration of the file.
      */
-    virtual int getMaxZoomLevel() const { return 4194304; } // 2^22, arbitrarily
+    virtual ZoomLevel getMaxZoomLevel() const {
+        return { ZoomLevel::FramesPerPixel, 4194304 }; // 2^22, arbitrarily
+    }
 };
 
 #endif
--- a/data/model/PowerOfSqrtTwoZoomConstraint.cpp	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfSqrtTwoZoomConstraint.cpp	Mon Sep 17 13:51:14 2018 +0100
@@ -19,13 +19,30 @@
 #include <cmath>
 
 
-int
-PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(int blockSize,
+ZoomLevel
+PowerOfSqrtTwoZoomConstraint::getNearestZoomLevel(ZoomLevel requested,
                                                   RoundingDirection dir) const
 {
     int type, power;
-    int rv = getNearestBlockSize(blockSize, type, power, dir);
-    return rv;
+    int blockSize;
+
+    if (requested.zone == ZoomLevel::FramesPerPixel) {
+        blockSize = getNearestBlockSize(requested.level, type, power, dir);
+        return { requested.zone, blockSize };
+    } else {
+        RoundingDirection opposite = dir;
+        if (dir == RoundUp) opposite = RoundDown;
+        else if (dir == RoundDown) opposite = RoundUp;
+        blockSize = getNearestBlockSize(requested.level, type, power, opposite);
+        if (blockSize > getMinZoomLevel().level) {
+            blockSize = getMinZoomLevel().level;
+        }
+        if (blockSize == 1) {
+            return { ZoomLevel::FramesPerPixel, 1 };
+        } else {
+            return { requested.zone, blockSize };
+        }
+    }
 }
 
 int
@@ -106,6 +123,9 @@
         prevBase = base;
     }
 
-    if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
+    if (result > getMaxZoomLevel().level) {
+        result = getMaxZoomLevel().level;
+    }
+
     return result;
 }   
--- a/data/model/PowerOfSqrtTwoZoomConstraint.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfSqrtTwoZoomConstraint.h	Mon Sep 17 13:51:14 2018 +0100
@@ -21,17 +21,17 @@
 class PowerOfSqrtTwoZoomConstraint : virtual public ZoomConstraint
 {
 public:
+    virtual ZoomLevel getNearestZoomLevel(ZoomLevel requested,
+                                          RoundingDirection dir = RoundNearest)
+	const override;
+	
+    virtual int getMinCachePower() const { return 6; }
+
     virtual int getNearestBlockSize(int requestedBlockSize,
-                                       RoundingDirection dir = RoundNearest)
+                                    int &type,
+                                    int &power,
+                                    RoundingDirection dir = RoundNearest)
         const;
-    
-    virtual int getNearestBlockSize(int requestedBlockSize,
-                                       int &type,
-                                       int &power,
-                                       RoundingDirection dir = RoundNearest)
-        const;
-        
-    virtual int getMinCachePower() const { return 6; }
 };
 
 #endif
--- a/data/model/PowerOfTwoZoomConstraint.cpp	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfTwoZoomConstraint.cpp	Mon Sep 17 13:51:14 2018 +0100
@@ -15,6 +15,34 @@
 
 #include "PowerOfTwoZoomConstraint.h"
 
+ZoomLevel
+PowerOfTwoZoomConstraint::getNearestZoomLevel(ZoomLevel requested,
+                                              RoundingDirection dir) const
+{
+    int blockSize;
+
+    if (requested.zone == ZoomLevel::FramesPerPixel) {
+        blockSize = getNearestBlockSize(requested.level, dir);
+        if (blockSize > getMaxZoomLevel().level) {
+            blockSize = getMaxZoomLevel().level;
+        }
+        return { requested.zone, blockSize };
+    } else {
+        RoundingDirection opposite = dir;
+        if (dir == RoundUp) opposite = RoundDown;
+        else if (dir == RoundDown) opposite = RoundUp;
+        blockSize = getNearestBlockSize(requested.level, opposite);
+        if (blockSize > getMinZoomLevel().level) {
+            blockSize = getMinZoomLevel().level;
+        }
+        if (blockSize == 1) {
+            return { ZoomLevel::FramesPerPixel, 1 };
+        } else {
+            return { requested.zone, blockSize };
+        }
+    }
+}
+
 int
 PowerOfTwoZoomConstraint::getNearestBlockSize(int req,
                                               RoundingDirection dir) const
@@ -41,7 +69,7 @@
         }
     }
 
-    if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
+    if (result > getMaxZoomLevel().level) result = getMaxZoomLevel().level;
     return result;
 }
 
--- a/data/model/PowerOfTwoZoomConstraint.h	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/PowerOfTwoZoomConstraint.h	Mon Sep 17 13:51:14 2018 +0100
@@ -21,8 +21,13 @@
 class PowerOfTwoZoomConstraint : virtual public ZoomConstraint
 {
 public:
-    virtual int getNearestBlockSize(int requestedBlockSize,
-                                       RoundingDirection dir = RoundNearest)
+    virtual ZoomLevel getNearestZoomLevel(ZoomLevel requested,
+                                          RoundingDirection dir = RoundNearest)
+	const override;
+
+protected:
+    virtual int getNearestBlockSize(int requested,
+                                    RoundingDirection dir = RoundNearest)
         const;
 };
 
--- a/data/model/ReadOnlyWaveFileModel.cpp	Fri Sep 14 15:32:43 2018 +0100
+++ b/data/model/ReadOnlyWaveFileModel.cpp	Mon Sep 17 13:51:14 2018 +0100
@@ -341,6 +341,7 @@
     int power = m_zoomConstraint.getMinCachePower();
     int roundedBlockSize = m_zoomConstraint.getNearestBlockSize
         (desired, cacheType, power, ZoomConstraint::RoundDown);
+
     if (cacheType != 0 && cacheType != 1) {
         // We will be reading directly from file, so can satisfy any
         // blocksize requirement