annotate data/model/PowerOfTwoZoomConstraint.cpp @ 1881:b504df98c3be

Ensure completion on output model is started at zero, so if it's checked before the input model has become ready and the transform has begun, it is not accidentally reported as complete (affected re-aligning models in Sonic Lineup when replacing the session)
author Chris Cannam
date Fri, 26 Jun 2020 11:45:39 +0100
parents bf32b26d1dad
children 1ae6a19464a7
rev   line source
Chris@147 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@147 2
Chris@147 3 /*
Chris@147 4 Sonic Visualiser
Chris@147 5 An audio file viewer and annotation editor.
Chris@147 6 Centre for Digital Music, Queen Mary, University of London.
Chris@147 7 This file copyright 2006 Chris Cannam.
Chris@147 8
Chris@147 9 This program is free software; you can redistribute it and/or
Chris@147 10 modify it under the terms of the GNU General Public License as
Chris@147 11 published by the Free Software Foundation; either version 2 of the
Chris@147 12 License, or (at your option) any later version. See the file
Chris@147 13 COPYING included with this distribution for more information.
Chris@147 14 */
Chris@147 15
Chris@147 16 #include "PowerOfTwoZoomConstraint.h"
Chris@147 17
Chris@1324 18 ZoomLevel
Chris@1324 19 PowerOfTwoZoomConstraint::getNearestZoomLevel(ZoomLevel requested,
Chris@1324 20 RoundingDirection dir) const
Chris@1324 21 {
Chris@1324 22 int blockSize;
Chris@1324 23
Chris@1324 24 if (requested.zone == ZoomLevel::FramesPerPixel) {
Chris@1324 25 blockSize = getNearestBlockSize(requested.level, dir);
Chris@1324 26 if (blockSize > getMaxZoomLevel().level) {
Chris@1324 27 blockSize = getMaxZoomLevel().level;
Chris@1324 28 }
Chris@1324 29 return { requested.zone, blockSize };
Chris@1324 30 } else {
Chris@1324 31 RoundingDirection opposite = dir;
Chris@1324 32 if (dir == RoundUp) opposite = RoundDown;
Chris@1324 33 else if (dir == RoundDown) opposite = RoundUp;
Chris@1324 34 blockSize = getNearestBlockSize(requested.level, opposite);
Chris@1324 35 if (blockSize > getMinZoomLevel().level) {
Chris@1324 36 blockSize = getMinZoomLevel().level;
Chris@1324 37 }
Chris@1324 38 if (blockSize == 1) {
Chris@1324 39 return { ZoomLevel::FramesPerPixel, 1 };
Chris@1324 40 } else {
Chris@1324 41 return { requested.zone, blockSize };
Chris@1324 42 }
Chris@1324 43 }
Chris@1324 44 }
Chris@1324 45
Chris@929 46 int
Chris@929 47 PowerOfTwoZoomConstraint::getNearestBlockSize(int req,
Chris@1429 48 RoundingDirection dir) const
Chris@147 49 {
Chris@1530 50 int max = getMaxZoomLevel().level;
Chris@147 51
Chris@1528 52 if (req > max) {
Chris@1528 53 return max;
Chris@1528 54 }
Chris@1528 55
Chris@1528 56 for (int bs = 1; bs <= max; bs *= 2) {
Chris@1528 57 if (bs < req) {
Chris@1528 58 continue;
Chris@1528 59 } else if (bs == req) {
Chris@1528 60 return bs;
Chris@1528 61 } else { // bs > req
Chris@1429 62 if (dir == RoundNearest) {
Chris@1429 63 if (bs - req < req - bs/2) {
Chris@1528 64 return bs;
Chris@1429 65 } else {
Chris@1528 66 return bs/2;
Chris@1429 67 }
Chris@1429 68 } else if (dir == RoundDown) {
Chris@1528 69 return bs/2;
Chris@1429 70 } else {
Chris@1528 71 return bs;
Chris@1429 72 }
Chris@1429 73 }
Chris@147 74 }
Chris@147 75
Chris@1528 76 return max;
Chris@147 77 }
Chris@147 78