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@1528
|
21 #include "base/Debug.h"
|
Chris@1528
|
22
|
Chris@147
|
23
|
Chris@929
|
24 int
|
Chris@929
|
25 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(int blockSize,
|
Chris@1429
|
26 RoundingDirection dir) const
|
Chris@147
|
27 {
|
Chris@147
|
28 int type, power;
|
Chris@929
|
29 int rv = getNearestBlockSize(blockSize, type, power, dir);
|
Chris@147
|
30 return rv;
|
Chris@147
|
31 }
|
Chris@147
|
32
|
Chris@929
|
33 int
|
Chris@929
|
34 PowerOfSqrtTwoZoomConstraint::getNearestBlockSize(int blockSize,
|
Chris@1429
|
35 int &type,
|
Chris@1429
|
36 int &power,
|
Chris@1429
|
37 RoundingDirection dir) const
|
Chris@147
|
38 {
|
Chris@1528
|
39 // SVCERR << "given " << blockSize << endl;
|
Chris@147
|
40
|
Chris@929
|
41 int minCachePower = getMinCachePower();
|
Chris@147
|
42
|
Chris@929
|
43 if (blockSize < (1 << minCachePower)) {
|
Chris@1429
|
44 type = -1;
|
Chris@1429
|
45 power = 0;
|
Chris@1429
|
46 float val = 1.0, prevVal = 1.0;
|
Chris@1429
|
47 while (val + 0.01 < blockSize) {
|
Chris@1429
|
48 prevVal = val;
|
Chris@1429
|
49 val *= sqrtf(2.f);
|
Chris@1429
|
50 }
|
Chris@1528
|
51 int rval = int(val + 0.01f);
|
Chris@1528
|
52 // SVCERR << "got val = " << val << ", rval = " << rval << ", prevVal = " << prevVal << endl;
|
Chris@1528
|
53 if (rval != blockSize && dir != RoundUp) {
|
Chris@1528
|
54 if (dir == RoundDown) {
|
Chris@1528
|
55 rval = int(prevVal + 0.01f);
|
Chris@1528
|
56 } else if (val - float(blockSize) < float(blockSize) - prevVal) {
|
Chris@1528
|
57 rval = int(val + 0.01f);
|
Chris@1528
|
58 } else {
|
Chris@1528
|
59 rval = int(prevVal + 0.01);
|
Chris@1528
|
60 }
|
Chris@1528
|
61 }
|
Chris@1528
|
62 // SVCERR << "returning " << rval << endl;
|
Chris@1429
|
63 return rval;
|
Chris@147
|
64 }
|
Chris@147
|
65
|
Chris@929
|
66 int prevBase = (1 << minCachePower);
|
Chris@929
|
67 int prevPower = minCachePower;
|
Chris@929
|
68 int prevType = 0;
|
Chris@147
|
69
|
Chris@929
|
70 int result = 0;
|
Chris@147
|
71
|
Chris@147
|
72 for (unsigned int i = 0; ; ++i) {
|
Chris@147
|
73
|
Chris@1429
|
74 power = minCachePower + i/2;
|
Chris@1429
|
75 type = i % 2;
|
Chris@147
|
76
|
Chris@1429
|
77 int base;
|
Chris@1429
|
78 if (type == 0) {
|
Chris@1429
|
79 base = (1 << power);
|
Chris@1429
|
80 } else {
|
Chris@1429
|
81 base = (((unsigned int)((1 << minCachePower) * sqrt(2.) + 0.01))
|
Chris@1429
|
82 << (power - minCachePower));
|
Chris@1429
|
83 }
|
Chris@147
|
84
|
Chris@1528
|
85 // SVCERR << "Testing base " << base << " (i = " << i << ", power = " << power << ", type = " << type << ")" << endl;
|
Chris@377
|
86
|
Chris@377
|
87 if (base == blockSize) {
|
Chris@377
|
88 result = base;
|
Chris@377
|
89 break;
|
Chris@377
|
90 }
|
Chris@377
|
91
|
Chris@1429
|
92 if (base > blockSize) {
|
Chris@1429
|
93 if (dir == RoundNearest) {
|
Chris@1429
|
94 if (base - blockSize < blockSize - prevBase) {
|
Chris@1429
|
95 dir = RoundUp;
|
Chris@1429
|
96 } else {
|
Chris@1429
|
97 dir = RoundDown;
|
Chris@1429
|
98 }
|
Chris@1429
|
99 }
|
Chris@1429
|
100 if (dir == RoundUp) {
|
Chris@1429
|
101 result = base;
|
Chris@1429
|
102 break;
|
Chris@1429
|
103 } else {
|
Chris@1429
|
104 type = prevType;
|
Chris@1429
|
105 power = prevPower;
|
Chris@1429
|
106 result = prevBase;
|
Chris@1429
|
107 break;
|
Chris@1429
|
108 }
|
Chris@1429
|
109 }
|
Chris@147
|
110
|
Chris@1429
|
111 prevType = type;
|
Chris@1429
|
112 prevPower = power;
|
Chris@1429
|
113 prevBase = base;
|
Chris@147
|
114 }
|
Chris@147
|
115
|
Chris@147
|
116 if (result > getMaxZoomLevel()) result = getMaxZoomLevel();
|
Chris@147
|
117 return result;
|
Chris@147
|
118 }
|