Mercurial > hg > svcore
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