diff data/model/Dense3DModelPeakCache.cpp @ 545:c603d9439b37

* Add peak cache type for 3d models
author Chris Cannam
date Wed, 04 Feb 2009 13:33:50 +0000
parents
children 95391b480e17
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/model/Dense3DModelPeakCache.cpp	Wed Feb 04 13:33:50 2009 +0000
@@ -0,0 +1,108 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2009 QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "Dense3DModelPeakCache.h"
+
+Dense3DModelPeakCache::Dense3DModelPeakCache(DenseThreeDimensionalModel *source,
+					     size_t columnsPerPeak) :
+    m_source(source),
+    m_resolution(columnsPerPeak)
+{
+    m_cache = new EditableDenseThreeDimensionalModel
+        (source->getSampleRate(),
+         getResolution(),
+         source->getHeight(),
+         EditableDenseThreeDimensionalModel::NoCompression,
+         false);
+
+    connect(source, SIGNAL(modelChanged()),
+            this, SLOT(sourceModelChanged()));
+    connect(source, SIGNAL(modelAboutToBeDeleted()),
+            this, SLOT(sourceModelAboutToBeDeleted()));
+
+}
+
+Dense3DModelPeakCache::~Dense3DModelPeakCache()
+{
+    delete m_cache;
+}
+
+bool
+Dense3DModelPeakCache::isColumnAvailable(size_t column) const
+{
+    if (!m_source) return false;
+    if (haveColumn(column)) return true;
+    for (int i = 0; i < m_resolution; ++i) {
+        if (!m_source->isColumnAvailable(column * m_resolution + i)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+Dense3DModelPeakCache::Column
+Dense3DModelPeakCache::getColumn(size_t column) const
+{
+    if (!m_source) return Column();
+    if (!haveColumn(column)) fillColumn(column);
+    return m_cache->getColumn(column);
+}
+
+float
+Dense3DModelPeakCache::getValueAt(size_t column, size_t n) const
+{
+    if (!m_source) return 0.f;
+    if (!haveColumn(column)) fillColumn(column);
+    return m_cache->getValueAt(column, n);
+}
+
+void
+Dense3DModelPeakCache::sourceModelChanged()
+{
+    if (!m_source) return;
+    m_coverage.resize(getWidth());
+}
+
+void
+Dense3DModelPeakCache::sourceModelAboutToBeDeleted()
+{
+    m_source = 0;
+}
+
+bool
+Dense3DModelPeakCache::haveColumn(size_t column) const
+{
+    return m_coverage.get(column);
+}
+
+void
+Dense3DModelPeakCache::fillColumn(size_t column) const
+{
+    Column peak;
+    for (int i = 0; i < m_resolution; ++i) {
+        Column here = m_source->getColumn(column * m_resolution + i);
+        if (i == 0) {
+            peak = here;
+        } else {
+            for (int j = 0; j < peak.size() && j < here.size(); ++j) {
+                if (here[j] > peak[j]) peak[j] = here[j];
+            }
+        }
+    }
+    m_cache->setColumn(column, peak);
+    m_coverage.set(column);
+}
+
+