annotate data/model/Dense3DModelPeakCache.cpp @ 833:3cc81dbc31bb

Use thread-local storage for network managers; otherwise we get "Cannot create children for a parent that is in a different thread" from nm.get()
author Chris Cannam
date Fri, 19 Jul 2013 13:47:11 +0100
parents bbe503e368a9
children 59e7fe1b1003
rev   line source
Chris@545 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@545 2
Chris@545 3 /*
Chris@545 4 Sonic Visualiser
Chris@545 5 An audio file viewer and annotation editor.
Chris@545 6 Centre for Digital Music, Queen Mary, University of London.
Chris@545 7 This file copyright 2009 QMUL.
Chris@545 8
Chris@545 9 This program is free software; you can redistribute it and/or
Chris@545 10 modify it under the terms of the GNU General Public License as
Chris@545 11 published by the Free Software Foundation; either version 2 of the
Chris@545 12 License, or (at your option) any later version. See the file
Chris@545 13 COPYING included with this distribution for more information.
Chris@545 14 */
Chris@545 15
Chris@545 16 #include "Dense3DModelPeakCache.h"
Chris@545 17
Chris@551 18 #include "base/Profiler.h"
Chris@551 19
Chris@545 20 Dense3DModelPeakCache::Dense3DModelPeakCache(DenseThreeDimensionalModel *source,
Chris@545 21 size_t columnsPerPeak) :
Chris@545 22 m_source(source),
Chris@545 23 m_resolution(columnsPerPeak)
Chris@545 24 {
Chris@546 25 m_coverage.resize(1); // otherwise it is simply invalid
Chris@546 26
Chris@545 27 m_cache = new EditableDenseThreeDimensionalModel
Chris@545 28 (source->getSampleRate(),
Chris@545 29 getResolution(),
Chris@545 30 source->getHeight(),
Chris@545 31 EditableDenseThreeDimensionalModel::NoCompression,
Chris@545 32 false);
Chris@545 33
Chris@545 34 connect(source, SIGNAL(modelChanged()),
Chris@545 35 this, SLOT(sourceModelChanged()));
Chris@546 36 connect(source, SIGNAL(aboutToBeDeleted()),
Chris@545 37 this, SLOT(sourceModelAboutToBeDeleted()));
Chris@545 38
Chris@545 39 }
Chris@545 40
Chris@545 41 Dense3DModelPeakCache::~Dense3DModelPeakCache()
Chris@545 42 {
Chris@545 43 delete m_cache;
Chris@545 44 }
Chris@545 45
Chris@545 46 bool
Chris@545 47 Dense3DModelPeakCache::isColumnAvailable(size_t column) const
Chris@545 48 {
Chris@545 49 if (!m_source) return false;
Chris@545 50 if (haveColumn(column)) return true;
Chris@552 51 for (int i = m_resolution; i > 0; ) {
Chris@552 52 --i;
Chris@545 53 if (!m_source->isColumnAvailable(column * m_resolution + i)) {
Chris@545 54 return false;
Chris@545 55 }
Chris@545 56 }
Chris@545 57 return true;
Chris@545 58 }
Chris@545 59
Chris@545 60 Dense3DModelPeakCache::Column
Chris@545 61 Dense3DModelPeakCache::getColumn(size_t column) const
Chris@545 62 {
Chris@551 63 Profiler profiler("Dense3DModelPeakCache::getColumn");
Chris@545 64 if (!m_source) return Column();
Chris@545 65 if (!haveColumn(column)) fillColumn(column);
Chris@545 66 return m_cache->getColumn(column);
Chris@545 67 }
Chris@545 68
Chris@545 69 float
Chris@545 70 Dense3DModelPeakCache::getValueAt(size_t column, size_t n) const
Chris@545 71 {
Chris@545 72 if (!m_source) return 0.f;
Chris@545 73 if (!haveColumn(column)) fillColumn(column);
Chris@545 74 return m_cache->getValueAt(column, n);
Chris@545 75 }
Chris@545 76
Chris@545 77 void
Chris@545 78 Dense3DModelPeakCache::sourceModelChanged()
Chris@545 79 {
Chris@545 80 if (!m_source) return;
Chris@546 81 if (m_coverage.size() > 0) {
Chris@546 82 // The last peak may have come from an incomplete read, which
Chris@546 83 // may since have been filled, so reset it
Chris@546 84 m_coverage.reset(m_coverage.size()-1);
Chris@546 85 }
Chris@548 86 m_coverage.resize(getWidth()); // retaining data
Chris@545 87 }
Chris@545 88
Chris@545 89 void
Chris@545 90 Dense3DModelPeakCache::sourceModelAboutToBeDeleted()
Chris@545 91 {
Chris@545 92 m_source = 0;
Chris@545 93 }
Chris@545 94
Chris@545 95 bool
Chris@545 96 Dense3DModelPeakCache::haveColumn(size_t column) const
Chris@545 97 {
Chris@546 98 return column < m_coverage.size() && m_coverage.get(column);
Chris@545 99 }
Chris@545 100
Chris@545 101 void
Chris@545 102 Dense3DModelPeakCache::fillColumn(size_t column) const
Chris@545 103 {
Chris@551 104 Profiler profiler("Dense3DModelPeakCache::fillColumn");
Chris@551 105
Chris@551 106 if (column >= m_coverage.size()) {
Chris@551 107 // see note in sourceModelChanged
Chris@551 108 if (m_coverage.size() > 0) m_coverage.reset(m_coverage.size()-1);
Chris@551 109 m_coverage.resize(column + 1);
Chris@551 110 }
Chris@546 111
Chris@545 112 Column peak;
Chris@545 113 for (int i = 0; i < m_resolution; ++i) {
Chris@545 114 Column here = m_source->getColumn(column * m_resolution + i);
Chris@545 115 if (i == 0) {
Chris@545 116 peak = here;
Chris@545 117 } else {
Chris@545 118 for (int j = 0; j < peak.size() && j < here.size(); ++j) {
Chris@545 119 if (here[j] > peak[j]) peak[j] = here[j];
Chris@545 120 }
Chris@545 121 }
Chris@545 122 }
Chris@546 123
Chris@545 124 m_cache->setColumn(column, peak);
Chris@545 125 m_coverage.set(column);
Chris@545 126 }
Chris@545 127
Chris@545 128