Mercurial > hg > svgui
comparison layer/ScrollableMagRangeCache.cpp @ 1216:dc2af6616c83
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:50 +0000 |
parents | f2f43802718b |
children | a34a2a25907c |
comparison
equal
deleted
inserted
replaced
1048:e8102ff5573b | 1216:dc2af6616c83 |
---|---|
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 | |
8 This program is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU General Public License as | |
10 published by the Free Software Foundation; either version 2 of the | |
11 License, or (at your option) any later version. See the file | |
12 COPYING included with this distribution for more information. | |
13 */ | |
14 | |
15 #include "ScrollableMagRangeCache.h" | |
16 | |
17 #include "base/HitCount.h" | |
18 | |
19 #include <iostream> | |
20 using namespace std; | |
21 | |
22 //#define DEBUG_SCROLLABLE_MAG_RANGE_CACHE 1 | |
23 | |
24 void | |
25 ScrollableMagRangeCache::scrollTo(const LayerGeometryProvider *v, | |
26 sv_frame_t newStartFrame) | |
27 { | |
28 static HitCount count("ScrollableMagRangeCache: scrolling"); | |
29 | |
30 int dx = (v->getXForFrame(m_startFrame) - | |
31 v->getXForFrame(newStartFrame)); | |
32 | |
33 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE | |
34 cerr << "ScrollableMagRangeCache::scrollTo: start frame " << m_startFrame | |
35 << " -> " << newStartFrame << ", dx = " << dx << endl; | |
36 #endif | |
37 | |
38 if (m_startFrame == newStartFrame) { | |
39 // haven't moved | |
40 count.hit(); | |
41 return; | |
42 } | |
43 | |
44 m_startFrame = newStartFrame; | |
45 | |
46 if (dx == 0) { | |
47 // haven't moved visibly (even though start frame may have changed) | |
48 count.hit(); | |
49 return; | |
50 } | |
51 | |
52 int w = int(m_ranges.size()); | |
53 | |
54 if (dx <= -w || dx >= w) { | |
55 // scrolled entirely off | |
56 invalidate(); | |
57 count.miss(); | |
58 return; | |
59 } | |
60 | |
61 count.partial(); | |
62 | |
63 // dx is in range, cache is scrollable | |
64 | |
65 if (dx < 0) { | |
66 // The new start frame is to the left of the old start | |
67 // frame. We need to add some empty ranges at the left (start) | |
68 // end and clip the right end. Assemble -dx new values, then | |
69 // w+dx old values starting at index 0. | |
70 | |
71 auto newRanges = vector<MagnitudeRange>(-dx); | |
72 newRanges.insert(newRanges.end(), | |
73 m_ranges.begin(), m_ranges.begin() + (w + dx)); | |
74 m_ranges = newRanges; | |
75 | |
76 } else { | |
77 // The new start frame is to the right of the old start | |
78 // frame. We want to clip the left (start) end and add some | |
79 // empty ranges at the right end. Assemble w-dx old values | |
80 // starting at index dx, then dx new values. | |
81 | |
82 auto newRanges = vector<MagnitudeRange>(dx); | |
83 newRanges.insert(newRanges.begin(), | |
84 m_ranges.begin() + dx, m_ranges.end()); | |
85 m_ranges = newRanges; | |
86 } | |
87 | |
88 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE | |
89 cerr << "maxes (" << m_ranges.size() << ") now: "; | |
90 for (int i = 0; in_range_for(m_ranges, i); ++i) { | |
91 cerr << m_ranges[i].getMax() << " "; | |
92 } | |
93 cerr << endl; | |
94 #endif | |
95 } | |
96 | |
97 MagnitudeRange | |
98 ScrollableMagRangeCache::getRange(int x, int count) const | |
99 { | |
100 MagnitudeRange r; | |
101 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE | |
102 cerr << "ScrollableMagRangeCache::getRange(" << x << ", " << count << ")" << endl; | |
103 #endif | |
104 for (int i = 0; i < count; ++i) { | |
105 r.sample(m_ranges.at(x + i)); | |
106 } | |
107 return r; | |
108 } | |
109 | |
110 void | |
111 ScrollableMagRangeCache::sampleColumn(int column, const MagnitudeRange &r) | |
112 { | |
113 if (!in_range_for(m_ranges, column)) { | |
114 cerr << "ERROR: ScrollableMagRangeCache::sampleColumn: column " << column | |
115 << " is out of range for cache of width " << m_ranges.size() | |
116 << " (with start frame " << m_startFrame << ")" << endl; | |
117 throw logic_error("column out of range"); | |
118 } else { | |
119 m_ranges[column].sample(r); | |
120 } | |
121 } | |
122 |