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 #include "base/Debug.h"
22 
23 
26  RoundingDirection dir) const
27 {
28  int type, power;
29  int blockSize;
30 
31  if (requested.zone == ZoomLevel::FramesPerPixel) {
32  blockSize = getNearestBlockSize(requested.level, type, power, dir);
33  return { requested.zone, blockSize };
34  } else {
35  RoundingDirection opposite = dir;
36  if (dir == RoundUp) opposite = RoundDown;
37  else if (dir == RoundDown) opposite = RoundUp;
38  blockSize = getNearestBlockSize(requested.level, type, power, opposite);
39  if (blockSize > getMinZoomLevel().level) {
40  blockSize = getMinZoomLevel().level;
41  }
42  if (blockSize == 1) {
43  return { ZoomLevel::FramesPerPixel, 1 };
44  } else {
45  return { requested.zone, blockSize };
46  }
47  }
48 }
49 
50 int
52  int &type,
53  int &power,
54  RoundingDirection dir) const
55 {
56 // SVCERR << "given " << blockSize << endl;
57 
58  int minCachePower = getMinCachePower();
59 
60  if (blockSize < (1 << minCachePower)) {
61  type = -1;
62  power = 0;
63  float val = 1.0, prevVal = 1.0;
64  while (val + 0.01 < blockSize) {
65  prevVal = val;
66  val *= sqrtf(2.f);
67  }
68  int rval = int(val + 0.01f);
69 // SVCERR << "got val = " << val << ", rval = " << rval << ", prevVal = " << prevVal << endl;
70  if (rval != blockSize && dir != RoundUp) {
71  if (dir == RoundDown) {
72  rval = int(prevVal + 0.01f);
73  } else if (val - float(blockSize) < float(blockSize) - prevVal) {
74  rval = int(val + 0.01f);
75  } else {
76  rval = int(prevVal + 0.01);
77  }
78  }
79 // SVCERR << "returning " << rval << endl;
80  return rval;
81  }
82 
83  int prevBase = (1 << minCachePower);
84  int prevPower = minCachePower;
85  int prevType = 0;
86 
87  int result = 0;
88 
89  for (unsigned int i = 0; ; ++i) {
90 
91  power = minCachePower + i/2;
92  type = i % 2;
93 
94  int base;
95  if (type == 0) {
96  base = (1 << power);
97  } else {
98  base = (((unsigned int)((1 << minCachePower) * sqrt(2.) + 0.01))
99  << (power - minCachePower));
100  }
101 
102 // SVCERR << "Testing base " << base << " (i = " << i << ", power = " << power << ", type = " << type << ")" << endl;
103 
104  if (base == blockSize) {
105  result = base;
106 // SVCERR << "Equal, accepting" << endl;
107  break;
108  }
109 
110  if (base > blockSize) {
111  if (dir == RoundNearest) {
112  if (base - blockSize < blockSize - prevBase) {
113  dir = RoundUp;
114 // SVCERR << "Closer to " << base << " than " << prevBase
115 // << ", rounding up" << endl;
116  } else {
117  dir = RoundDown;
118 // SVCERR << "Closer to " << prevBase << " than " << base
119 // << ", rounding down" << endl;
120  }
121  }
122  if (dir == RoundUp) {
123  result = base;
124  break;
125  } else {
126  type = prevType;
127  power = prevPower;
128  result = prevBase;
129  break;
130  }
131  }
132 
133  prevType = type;
134  prevPower = power;
135  prevBase = base;
136  }
137 
138  if (result > getMaxZoomLevel().level) {
139  result = getMaxZoomLevel().level;
140  }
141 
142 // SVCERR << "Returning result " << result << endl;
143 
144  return result;
145 }
virtual ZoomLevel getMaxZoomLevel() const
Return the maximum zoom level within range for this constraint.
virtual int getNearestBlockSize(int requestedBlockSize, int &type, int &power, RoundingDirection dir=RoundNearest) const
virtual ZoomLevel getMinZoomLevel() const
Return the minimum zoom level within range for this constraint.
Zone zone
Definition: ZoomLevel.h:33
Display zoom level.
Definition: ZoomLevel.h:26
int level
Definition: ZoomLevel.h:34
virtual ZoomLevel getNearestZoomLevel(ZoomLevel requested, RoundingDirection dir=RoundNearest) const override
Given an "ideal" zoom level (frames per pixel or pixels per frame) for a given zoom level...