annotate data/model/Dense3DModelPeakCache.cpp @ 1188:d9698ee93659 spectrogram-minor-refactor

Extend column logic to peak frequency display as well, and correct some scopes according to whether values are per source column or per target pixel
author Chris Cannam
date Mon, 20 Jun 2016 12:00:32 +0100
parents 2dc27f0f97ad
children f6998e304b36
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@929 21 int columnsPerPeak) :
Chris@545 22 m_source(source),
Chris@545 23 m_resolution(columnsPerPeak)
Chris@545 24 {
Chris@545 25 m_cache = new EditableDenseThreeDimensionalModel
Chris@545 26 (source->getSampleRate(),
Chris@545 27 getResolution(),
Chris@545 28 source->getHeight(),
Chris@545 29 EditableDenseThreeDimensionalModel::NoCompression,
Chris@545 30 false);
Chris@545 31
Chris@545 32 connect(source, SIGNAL(modelChanged()),
Chris@545 33 this, SLOT(sourceModelChanged()));
Chris@546 34 connect(source, SIGNAL(aboutToBeDeleted()),
Chris@545 35 this, SLOT(sourceModelAboutToBeDeleted()));
Chris@545 36
Chris@545 37 }
Chris@545 38
Chris@545 39 Dense3DModelPeakCache::~Dense3DModelPeakCache()
Chris@545 40 {
Chris@545 41 delete m_cache;
Chris@545 42 }
Chris@545 43
Chris@545 44 Dense3DModelPeakCache::Column
Chris@929 45 Dense3DModelPeakCache::getColumn(int column) const
Chris@545 46 {
Chris@551 47 Profiler profiler("Dense3DModelPeakCache::getColumn");
Chris@545 48 if (!m_source) return Column();
Chris@545 49 if (!haveColumn(column)) fillColumn(column);
Chris@545 50 return m_cache->getColumn(column);
Chris@545 51 }
Chris@545 52
Chris@545 53 float
Chris@929 54 Dense3DModelPeakCache::getValueAt(int column, int n) const
Chris@545 55 {
Chris@545 56 if (!m_source) return 0.f;
Chris@545 57 if (!haveColumn(column)) fillColumn(column);
Chris@545 58 return m_cache->getValueAt(column, n);
Chris@545 59 }
Chris@545 60
Chris@545 61 void
Chris@545 62 Dense3DModelPeakCache::sourceModelChanged()
Chris@545 63 {
Chris@545 64 if (!m_source) return;
Chris@546 65 if (m_coverage.size() > 0) {
Chris@546 66 // The last peak may have come from an incomplete read, which
Chris@546 67 // may since have been filled, so reset it
Chris@1153 68 m_coverage[m_coverage.size()-1] = false;
Chris@546 69 }
Chris@1153 70 m_coverage.resize(getWidth(), false); // retaining data
Chris@545 71 }
Chris@545 72
Chris@545 73 void
Chris@545 74 Dense3DModelPeakCache::sourceModelAboutToBeDeleted()
Chris@545 75 {
Chris@545 76 m_source = 0;
Chris@545 77 }
Chris@545 78
Chris@545 79 bool
Chris@929 80 Dense3DModelPeakCache::haveColumn(int column) const
Chris@545 81 {
Chris@1153 82 return in_range_for(m_coverage, column) && m_coverage[column];
Chris@545 83 }
Chris@545 84
Chris@545 85 void
Chris@929 86 Dense3DModelPeakCache::fillColumn(int column) const
Chris@545 87 {
Chris@551 88 Profiler profiler("Dense3DModelPeakCache::fillColumn");
Chris@551 89
Chris@1153 90 if (!in_range_for(m_coverage, column)) {
Chris@551 91 // see note in sourceModelChanged
Chris@1153 92 if (m_coverage.size() > 0) m_coverage[m_coverage.size()-1] = false;
Chris@1153 93 m_coverage.resize(column + 1, false);
Chris@551 94 }
Chris@546 95
Chris@545 96 Column peak;
Chris@1156 97 int n = 0;
Chris@1153 98 for (int i = 0; i < m_resolution; ++i) {
Chris@545 99 Column here = m_source->getColumn(column * m_resolution + i);
Chris@545 100 if (i == 0) {
Chris@545 101 peak = here;
Chris@1156 102 n = int(peak.size());
Chris@545 103 } else {
Chris@1156 104 int m = std::min(n, int(here.size()));
Chris@1156 105 for (int j = 0; j < m; ++j) {
Chris@1156 106 peak[j] = std::max(here[j], peak[j]);
Chris@545 107 }
Chris@545 108 }
Chris@545 109 }
Chris@546 110
Chris@545 111 m_cache->setColumn(column, peak);
Chris@1153 112 m_coverage[column] = true;
Chris@545 113 }
Chris@545 114
Chris@545 115