svcore  1.9
PowerOfSqrtTwoZoomConstraint.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
17 
18 #include <iostream>
19 #include <cmath>
20 
21 
22 int
24  RoundingDirection dir) const
25 {
26  int type, power;
27  int rv = getNearestBlockSize(blockSize, type, power, dir);
28  return rv;
29 }
30 
31 int
33  int &type,
34  int &power,
35  RoundingDirection dir) const
36 {
37 // cerr << "given " << blockSize << endl;
38 
39  int minCachePower = getMinCachePower();
40 
41  if (blockSize < (1 << minCachePower)) {
42  type = -1;
43  power = 0;
44  float val = 1.0, prevVal = 1.0;
45  while (val + 0.01 < blockSize) {
46  prevVal = val;
47  val *= sqrt(2.f);
48  }
49  int rval;
50  if (dir == RoundUp) rval = int(val + 0.01);
51  else if (dir == RoundDown) rval = int(prevVal + 0.01);
52  else if (val - blockSize < blockSize - prevVal) rval = int(val + 0.01);
53  else rval = int(prevVal + 0.01);
54 // SVDEBUG << "returning " << rval << endl;
55  return rval;
56  }
57 
58  int prevBase = (1 << minCachePower);
59  int prevPower = minCachePower;
60  int prevType = 0;
61 
62  int result = 0;
63 
64  for (unsigned int i = 0; ; ++i) {
65 
66  power = minCachePower + i/2;
67  type = i % 2;
68 
69  int base;
70  if (type == 0) {
71  base = (1 << power);
72  } else {
73  base = (((unsigned int)((1 << minCachePower) * sqrt(2.) + 0.01))
74  << (power - minCachePower));
75  }
76 
77 // SVDEBUG << "Testing base " << base << endl;
78 
79  if (base == blockSize) {
80  result = base;
81  break;
82  }
83 
84  if (base > blockSize) {
85  if (dir == RoundNearest) {
86  if (base - blockSize < blockSize - prevBase) {
87  dir = RoundUp;
88  } else {
89  dir = RoundDown;
90  }
91  }
92  if (dir == RoundUp) {
93  result = base;
94  break;
95  } else {
96  type = prevType;
97  power = prevPower;
98  result = prevBase;
99  break;
100  }
101  }
102 
103  prevType = type;
104  prevPower = power;
105  prevBase = base;
106  }
107 
108  if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
109  return result;
110 }
virtual int getMaxZoomLevel() const
Return the maximum zoom level within range for this constraint.
virtual int getNearestBlockSize(int requestedBlockSize, RoundingDirection dir=RoundNearest) const
Given the "ideal" block size (frames per pixel) for a given zoom level, return the nearest viable blo...