annotate data/model/PowerOfSqrtTwoZoomConstraint.cpp @ 985:f073d924a7c3

Fix #1058 clicking row in Layer Edit dialog when colour 3d plot layer active jumps to wrong frame (was using sample rate where resolution intended)
author Chris Cannam
date Tue, 16 Sep 2014 10:29:19 +0100
parents 59e7fe1b1003
children cc27f35aa75c
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 "PowerOfSqrtTwoZoomConstraint.h"
Chris@147 17
Chris@147 18 #include <iostream>
Chris@147 19 #include <cmath>
Chris@147 20
Chris@147 21
Chris@929 22 int
Chris@929 23 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(int blockSize,
Chris@147 24 RoundingDirection dir) const
Chris@147 25 {
Chris@147 26 int type, power;
Chris@929 27 int rv = getNearestBlockSize(blockSize, type, power, dir);
Chris@147 28 return rv;
Chris@147 29 }
Chris@147 30
Chris@929 31 int
Chris@929 32 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(int blockSize,
Chris@147 33 int &type,
Chris@147 34 int &power,
Chris@147 35 RoundingDirection dir) const
Chris@147 36 {
Chris@843 37 // cerr << "given " << blockSize << endl;
Chris@147 38
Chris@929 39 int minCachePower = getMinCachePower();
Chris@147 40
Chris@929 41 if (blockSize < (1 << minCachePower)) {
Chris@147 42 type = -1;
Chris@147 43 power = 0;
Chris@147 44 float val = 1.0, prevVal = 1.0;
Chris@147 45 while (val + 0.01 < blockSize) {
Chris@147 46 prevVal = val;
Chris@608 47 val *= sqrt(2.f);
Chris@147 48 }
Chris@929 49 int rval;
Chris@929 50 if (dir == RoundUp) rval = int(val + 0.01);
Chris@929 51 else if (dir == RoundDown) rval = int(prevVal + 0.01);
Chris@929 52 else if (val - blockSize < blockSize - prevVal) rval = int(val + 0.01);
Chris@929 53 else rval = int(prevVal + 0.01);
Chris@690 54 // SVDEBUG << "returning " << rval << endl;
Chris@147 55 return rval;
Chris@147 56 }
Chris@147 57
Chris@929 58 int prevBase = (1 << minCachePower);
Chris@929 59 int prevPower = minCachePower;
Chris@929 60 int prevType = 0;
Chris@147 61
Chris@929 62 int result = 0;
Chris@147 63
Chris@147 64 for (unsigned int i = 0; ; ++i) {
Chris@147 65
Chris@147 66 power = minCachePower + i/2;
Chris@147 67 type = i % 2;
Chris@147 68
Chris@929 69 int base;
Chris@147 70 if (type == 0) {
Chris@147 71 base = (1 << power);
Chris@147 72 } else {
Chris@608 73 base = (((unsigned int)((1 << minCachePower) * sqrt(2.) + 0.01))
Chris@147 74 << (power - minCachePower));
Chris@147 75 }
Chris@147 76
Chris@690 77 // SVDEBUG << "Testing base " << base << endl;
Chris@377 78
Chris@377 79 if (base == blockSize) {
Chris@377 80 result = base;
Chris@377 81 break;
Chris@377 82 }
Chris@377 83
Chris@377 84 if (base > blockSize) {
Chris@147 85 if (dir == RoundNearest) {
Chris@147 86 if (base - blockSize < blockSize - prevBase) {
Chris@147 87 dir = RoundUp;
Chris@147 88 } else {
Chris@147 89 dir = RoundDown;
Chris@147 90 }
Chris@147 91 }
Chris@147 92 if (dir == RoundUp) {
Chris@147 93 result = base;
Chris@147 94 break;
Chris@147 95 } else {
Chris@147 96 type = prevType;
Chris@147 97 power = prevPower;
Chris@147 98 result = prevBase;
Chris@147 99 break;
Chris@147 100 }
Chris@147 101 }
Chris@147 102
Chris@147 103 prevType = type;
Chris@147 104 prevPower = power;
Chris@147 105 prevBase = base;
Chris@147 106 }
Chris@147 107
Chris@147 108 if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
Chris@147 109 return result;
Chris@147 110 }