annotate layer/RenderTimer.h @ 1127:9fb8dfd7ce4c spectrogram-minor-refactor

Fix threshold in spectrogram -- it wasn't working in the last release. There is a new protocol for this. Formerly the threshold parameter had a range from -50dB to 0 with the default at -50, and -50 treated internally as "no threshold". However, there was a hardcoded, hidden internal threshold for spectrogram colour mapping at -80dB with anything below this being rounded to zero. Now the threshold parameter has range -81 to -1 with the default at -80, -81 is treated internally as "no threshold", and there is no hidden internal threshold. So the default behaviour is the same as before, an effective -80dB threshold, but it is now possible to change this in both directions. Sessions reloaded from prior versions may look slightly different because, if the session says there should be no threshold, there will now actually be no threshold instead of having the hidden internal one. Still need to do something in the UI to make it apparent that the -81dB setting removes the threshold entirely. This is at least no worse than the previous, also obscured, magic -50dB setting.
author Chris Cannam
date Mon, 01 Aug 2016 16:21:01 +0100
parents 6f98aa5291d4
children eaab8bab3522
rev   line source
Chris@1074 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1074 2
Chris@1074 3 /*
Chris@1074 4 Sonic Visualiser
Chris@1074 5 An audio file viewer and annotation editor.
Chris@1074 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1074 7
Chris@1074 8 This program is free software; you can redistribute it and/or
Chris@1074 9 modify it under the terms of the GNU General Public License as
Chris@1074 10 published by the Free Software Foundation; either version 2 of the
Chris@1074 11 License, or (at your option) any later version. See the file
Chris@1074 12 COPYING included with this distribution for more information.
Chris@1074 13 */
Chris@1074 14
Chris@1074 15 #ifndef RENDER_TIMER_H
Chris@1074 16 #define RENDER_TIMER_H
Chris@1074 17
Chris@1074 18 #include <chrono>
Chris@1074 19
Chris@1074 20 class RenderTimer
Chris@1074 21 {
Chris@1074 22 public:
Chris@1074 23 enum Type {
Chris@1074 24 /// A normal rendering operation with normal responsiveness demands
Chris@1074 25 FastRender,
Chris@1074 26
Chris@1074 27 /// An operation that the user might accept being slower
Chris@1074 28 SlowRender,
Chris@1074 29
Chris@1074 30 /// An operation that should always complete, i.e. as if there
Chris@1074 31 /// were no RenderTimer in use, but without having to change
Chris@1074 32 /// client code structurally
Chris@1074 33 NoTimeout
Chris@1074 34 };
Chris@1074 35
Chris@1074 36 /**
Chris@1074 37 * Create a new RenderTimer and start timing. Make one of these
Chris@1074 38 * before rendering, and then call outOfTime() regularly during
Chris@1074 39 * rendering. If outOfTime() returns true, abandon rendering! and
Chris@1074 40 * schedule the rest for after some user responsiveness has
Chris@1074 41 * happened.
Chris@1074 42 */
Chris@1074 43 RenderTimer(Type t) :
Chris@1074 44 m_start(std::chrono::steady_clock::now()),
Chris@1074 45 m_haveLimits(true),
Chris@1074 46 m_minFraction(0.1),
Chris@1074 47 m_softLimit(0.1),
Chris@1074 48 m_hardLimit(0.2),
Chris@1074 49 m_softLimitOverridden(false) {
Chris@1074 50
Chris@1074 51 if (t == NoTimeout) {
Chris@1074 52 m_haveLimits = false;
Chris@1074 53 } else if (t == SlowRender) {
Chris@1074 54 m_softLimit = 0.2;
Chris@1074 55 m_hardLimit = 0.4;
Chris@1074 56 }
Chris@1074 57 }
Chris@1074 58
Chris@1074 59
Chris@1074 60 /**
Chris@1074 61 * Return true if we have run out of time and should suspend
Chris@1074 62 * rendering and handle user events instead. Call this regularly
Chris@1074 63 * during rendering work: fractionComplete should be an estimate
Chris@1074 64 * of how much of the work has been done as of this call, as a
Chris@1074 65 * number between 0.0 (none of it) and 1.0 (all of it).
Chris@1074 66 */
Chris@1074 67 bool outOfTime(double fractionComplete) {
Chris@1074 68
Chris@1074 69 if (!m_haveLimits || fractionComplete < m_minFraction) {
Chris@1074 70 return false;
Chris@1074 71 }
Chris@1074 72
Chris@1074 73 auto t = std::chrono::steady_clock::now();
Chris@1074 74 double elapsed = std::chrono::duration<double>(t - m_start).count();
Chris@1074 75
Chris@1074 76 if (elapsed > m_hardLimit) {
Chris@1074 77 return true;
Chris@1074 78 } else if (!m_softLimitOverridden && elapsed > m_softLimit) {
Chris@1074 79 if (fractionComplete > 0.6) {
Chris@1074 80 // If we're significantly more than half way by the
Chris@1074 81 // time we reach the soft limit, ignore it (though
Chris@1074 82 // always respect the hard limit, above). Otherwise
Chris@1074 83 // respect the soft limit and report out of time now.
Chris@1074 84 m_softLimitOverridden = true;
Chris@1074 85 } else {
Chris@1074 86 return true;
Chris@1074 87 }
Chris@1074 88 }
Chris@1074 89
Chris@1074 90 return false;
Chris@1074 91 }
Chris@1074 92
Chris@1074 93 private:
Chris@1074 94 std::chrono::time_point<std::chrono::steady_clock> m_start;
Chris@1074 95 bool m_haveLimits;
Chris@1074 96 double m_minFraction;
Chris@1074 97 double m_softLimit;
Chris@1074 98 double m_hardLimit;
Chris@1074 99 bool m_softLimitOverridden;
Chris@1074 100 };
Chris@1074 101
Chris@1074 102 #endif