annotate layer/ScrollableMagRangeCache.cpp @ 1496:d09345e578a7

Separate out handling of alignment progress bar from the layer progress bars and fix tendency to have them hanging around even when alignment has completed
author Chris Cannam
date Wed, 14 Aug 2019 10:58:24 +0100
parents 6dc3a36d9794
children
rev   line source
Chris@1118 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1118 2
Chris@1118 3 /*
Chris@1118 4 Sonic Visualiser
Chris@1118 5 An audio file viewer and annotation editor.
Chris@1118 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1118 7
Chris@1118 8 This program is free software; you can redistribute it and/or
Chris@1118 9 modify it under the terms of the GNU General Public License as
Chris@1118 10 published by the Free Software Foundation; either version 2 of the
Chris@1118 11 License, or (at your option) any later version. See the file
Chris@1118 12 COPYING included with this distribution for more information.
Chris@1118 13 */
Chris@1118 14
Chris@1118 15 #include "ScrollableMagRangeCache.h"
Chris@1118 16
Chris@1164 17 #include "base/HitCount.h"
Chris@1411 18 #include "base/Debug.h"
Chris@1164 19
Chris@1118 20 #include <iostream>
Chris@1118 21 using namespace std;
Chris@1118 22
Chris@1143 23 //#define DEBUG_SCROLLABLE_MAG_RANGE_CACHE 1
Chris@1118 24
Chris@1118 25 void
Chris@1118 26 ScrollableMagRangeCache::scrollTo(const LayerGeometryProvider *v,
Chris@1266 27 sv_frame_t newStartFrame)
Chris@1266 28 {
Chris@1164 29 static HitCount count("ScrollableMagRangeCache: scrolling");
Chris@1164 30
Chris@1118 31 int dx = (v->getXForFrame(m_startFrame) -
Chris@1266 32 v->getXForFrame(newStartFrame));
Chris@1118 33
Chris@1118 34 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE
Chris@1411 35 SVDEBUG << "ScrollableMagRangeCache::scrollTo: start frame " << m_startFrame
Chris@1411 36 << " -> " << newStartFrame << ", dx = " << dx << endl;
Chris@1118 37 #endif
Chris@1122 38
Chris@1122 39 if (m_startFrame == newStartFrame) {
Chris@1266 40 // haven't moved
Chris@1164 41 count.hit();
Chris@1122 42 return;
Chris@1122 43 }
Chris@1118 44
Chris@1118 45 m_startFrame = newStartFrame;
Chris@1118 46
Chris@1118 47 if (dx == 0) {
Chris@1266 48 // haven't moved visibly (even though start frame may have changed)
Chris@1164 49 count.hit();
Chris@1266 50 return;
Chris@1118 51 }
Chris@1266 52
Chris@1118 53 int w = int(m_ranges.size());
Chris@1118 54
Chris@1118 55 if (dx <= -w || dx >= w) {
Chris@1266 56 // scrolled entirely off
Chris@1266 57 invalidate();
Chris@1164 58 count.miss();
Chris@1266 59 return;
Chris@1118 60 }
Chris@1164 61
Chris@1164 62 count.partial();
Chris@1266 63
Chris@1118 64 // dx is in range, cache is scrollable
Chris@1118 65
Chris@1118 66 if (dx < 0) {
Chris@1266 67 // The new start frame is to the left of the old start
Chris@1266 68 // frame. We need to add some empty ranges at the left (start)
Chris@1266 69 // end and clip the right end. Assemble -dx new values, then
Chris@1266 70 // w+dx old values starting at index 0.
Chris@1118 71
Chris@1266 72 auto newRanges = vector<MagnitudeRange>(-dx);
Chris@1266 73 newRanges.insert(newRanges.end(),
Chris@1266 74 m_ranges.begin(), m_ranges.begin() + (w + dx));
Chris@1266 75 m_ranges = newRanges;
Chris@1266 76
Chris@1118 77 } else {
Chris@1266 78 // The new start frame is to the right of the old start
Chris@1266 79 // frame. We want to clip the left (start) end and add some
Chris@1266 80 // empty ranges at the right end. Assemble w-dx old values
Chris@1266 81 // starting at index dx, then dx new values.
Chris@1118 82
Chris@1266 83 auto newRanges = vector<MagnitudeRange>(dx);
Chris@1266 84 newRanges.insert(newRanges.begin(),
Chris@1266 85 m_ranges.begin() + dx, m_ranges.end());
Chris@1266 86 m_ranges = newRanges;
Chris@1118 87 }
Chris@1122 88
Chris@1143 89 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE
Chris@1411 90 SVDEBUG << "maxes (" << m_ranges.size() << ") now: ";
Chris@1136 91 for (int i = 0; in_range_for(m_ranges, i); ++i) {
Chris@1411 92 SVDEBUG << m_ranges[i].getMax() << " ";
Chris@1136 93 }
Chris@1411 94 SVDEBUG << endl;
Chris@1143 95 #endif
Chris@1122 96 }
Chris@1122 97
Chris@1122 98 MagnitudeRange
Chris@1122 99 ScrollableMagRangeCache::getRange(int x, int count) const
Chris@1122 100 {
Chris@1122 101 MagnitudeRange r;
Chris@1122 102 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE
Chris@1411 103 SVDEBUG << "ScrollableMagRangeCache::getRange(" << x << ", " << count << ")" << endl;
Chris@1122 104 #endif
Chris@1122 105 for (int i = 0; i < count; ++i) {
Chris@1411 106 const auto &cr = m_ranges.at(x + i);
Chris@1411 107 if (cr.isSet()) {
Chris@1411 108 r.sample(cr);
Chris@1411 109 }
Chris@1411 110 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE
Chris@1411 111 SVDEBUG << cr.getMin() << "->" << cr.getMax() << " ";
Chris@1411 112 #endif
Chris@1122 113 }
Chris@1411 114 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE
Chris@1411 115 SVDEBUG << endl;
Chris@1411 116 #endif
Chris@1122 117 return r;
Chris@1118 118 }
Chris@1118 119
Chris@1118 120 void
Chris@1120 121 ScrollableMagRangeCache::sampleColumn(int column, const MagnitudeRange &r)
Chris@1120 122 {
Chris@1120 123 if (!in_range_for(m_ranges, column)) {
Chris@1411 124 SVCERR << "ERROR: ScrollableMagRangeCache::sampleColumn: column " << column
Chris@1411 125 << " is out of range for cache of width " << m_ranges.size()
Chris@1411 126 << " (with start frame " << m_startFrame << ")" << endl;
Chris@1266 127 throw logic_error("column out of range");
Chris@1120 128 } else {
Chris@1266 129 m_ranges[column].sample(r);
Chris@1120 130 }
Chris@1120 131 }
Chris@1120 132