changeset 377:166c22eff678

* Ensure waveforms are strictly correct even when using a non-power-of-two non-power-of-sqrt-two block size with cacheing off and painting only small areas at a time
author Chris Cannam
date Thu, 07 Feb 2008 15:25:05 +0000
parents ab24af1271e9
children a38cd7823cb2
files data/fileio/WavFileReader.cpp data/model/AggregateWaveModel.cpp data/model/AggregateWaveModel.h data/model/PowerOfSqrtTwoZoomConstraint.cpp data/model/RangeSummarisableTimeValueModel.h data/model/WaveFileModel.cpp data/model/WaveFileModel.h data/model/WritableWaveFileModel.cpp data/model/WritableWaveFileModel.h
diffstat 9 files changed, 71 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/data/fileio/WavFileReader.cpp	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/fileio/WavFileReader.cpp	Thu Feb 07 15:25:05 2008 +0000
@@ -111,6 +111,7 @@
 {
     if (count == 0) return;
     results.clear();
+    results.reserve(count * m_fileInfo.channels);
 
     QMutexLocker locker(&m_mutex);
 
--- a/data/model/AggregateWaveModel.cpp	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/AggregateWaveModel.cpp	Thu Feb 07 15:25:05 2008 +0000
@@ -190,6 +190,13 @@
     
     return min;
 }
+
+size_t
+AggregateWaveModel::getSummaryBlockSize(size_t desired) const
+{
+    //!!! complete
+    return desired;
+}
         
 void
 AggregateWaveModel::getSummaries(size_t channel, size_t start, size_t count,
--- a/data/model/AggregateWaveModel.h	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/AggregateWaveModel.h	Thu Feb 07 15:25:05 2008 +0000
@@ -71,6 +71,8 @@
                            size_t start, size_t count,
                            float **buffer) const;
 
+    virtual size_t getSummaryBlockSize(size_t desired) const;
+
     virtual void getSummaries(size_t channel, size_t start, size_t count,
                               RangeBlock &ranges,
                               size_t &blockSize) const;
--- a/data/model/PowerOfSqrtTwoZoomConstraint.cpp	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/PowerOfSqrtTwoZoomConstraint.cpp	Thu Feb 07 15:25:05 2008 +0000
@@ -75,7 +75,13 @@
 	}
 
 //	std::cerr << "Testing base " << base << std::endl;
-	if (base >= blockSize) {
+
+        if (base == blockSize) {
+            result = base;
+            break;
+        }
+
+	if (base > blockSize) {
 	    if (dir == RoundNearest) {
 		if (base - blockSize < blockSize - prevBase) {
 		    dir = RoundUp;
--- a/data/model/RangeSummarisableTimeValueModel.h	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/RangeSummarisableTimeValueModel.h	Thu Feb 07 15:25:05 2008 +0000
@@ -72,6 +72,8 @@
      */
     virtual Range getSummary(size_t channel, size_t start, size_t count) const = 0;
 
+    virtual size_t getSummaryBlockSize(size_t desired) const = 0;
+
     QString getTypeName() const { return tr("Range-Summarisable Time-Value"); }
 };
 
--- a/data/model/WaveFileModel.cpp	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/WaveFileModel.cpp	Thu Feb 07 15:25:05 2008 +0000
@@ -379,12 +379,29 @@
     return i;
 }
 
+size_t
+WaveFileModel::getSummaryBlockSize(size_t desired) const
+{
+    int cacheType = 0;
+    int power = m_zoomConstraint.getMinCachePower();
+    size_t roundedBlockSize = m_zoomConstraint.getNearestBlockSize
+        (desired, cacheType, power, ZoomConstraint::RoundDown);
+    if (cacheType != 0 && cacheType != 1) {
+        // We will be reading directly from file, so can satisfy any
+        // blocksize requirement
+        return desired;
+    } else {
+        return roundedBlockSize;
+    }
+}    
+
 void
 WaveFileModel::getSummaries(size_t channel, size_t start, size_t count,
                             RangeBlock &ranges, size_t &blockSize) const
 {
     ranges.clear();
     if (!isOK()) return;
+    ranges.reserve((count / blockSize) + 1);
 
     if (start > m_startFrame) start -= m_startFrame;
     else if (count <= m_startFrame - start) return;
@@ -395,8 +412,8 @@
 
     int cacheType = 0;
     int power = m_zoomConstraint.getMinCachePower();
-    blockSize = m_zoomConstraint.getNearestBlockSize
-        (blockSize, cacheType, power, ZoomConstraint::RoundUp);
+    size_t roundedBlockSize = m_zoomConstraint.getNearestBlockSize
+        (blockSize, cacheType, power, ZoomConstraint::RoundDown);
 
     size_t channels = getChannelCount();
 
@@ -410,17 +427,26 @@
 	// matter by putting a single cache in getInterleavedFrames
 	// for short queries.
 
-	SampleBlock frames;
-	m_reader->getInterleavedFrames(start, count, frames);
+        m_directReadMutex.lock();
+
+        if (m_lastDirectReadStart != start ||
+            m_lastDirectReadCount != count ||
+            m_directRead.empty()) {
+
+            m_reader->getInterleavedFrames(start, count, m_directRead);
+            m_lastDirectReadStart = start;
+            m_lastDirectReadCount = count;
+        }
+
 	float max = 0.0, min = 0.0, total = 0.0;
 	size_t i = 0, got = 0;
 
 	while (i < count) {
 
 	    size_t index = i * channels + channel;
-	    if (index >= frames.size()) break;
+	    if (index >= m_directRead.size()) break;
             
-	    float sample = frames[index];
+	    float sample = m_directRead[index];
             if (sample > max || got == 0) max = sample;
 	    if (sample < min || got == 0) min = sample;
             total += fabsf(sample);
@@ -435,6 +461,8 @@
 	    }
 	}
 
+        m_directReadMutex.unlock();
+
 	if (got > 0) {
             ranges.push_back(Range(min, max, total / got));
 	}
@@ -447,6 +475,8 @@
     
 	const RangeBlock &cache = m_cache[cacheType];
 
+        blockSize = roundedBlockSize;
+
 	size_t cacheBlock, div;
         
 	if (cacheType == 0) {
--- a/data/model/WaveFileModel.h	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/WaveFileModel.h	Thu Feb 07 15:25:05 2008 +0000
@@ -72,6 +72,8 @@
                            size_t start, size_t count,
                            float **buffers) const;
 
+    virtual size_t getSummaryBlockSize(size_t desired) const;
+
     virtual void getSummaries(size_t channel, size_t start, size_t count,
                               RangeBlock &ranges,
                               size_t &blockSize) const;
@@ -128,6 +130,11 @@
     size_t m_lastFillExtent;
     bool m_exiting;
     static PowerOfSqrtTwoZoomConstraint m_zoomConstraint;
+
+    mutable SampleBlock m_directRead;
+    mutable size_t m_lastDirectReadStart;
+    mutable size_t m_lastDirectReadCount;
+    mutable QMutex m_directReadMutex;
 };    
 
 #endif
--- a/data/model/WritableWaveFileModel.cpp	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/WritableWaveFileModel.cpp	Thu Feb 07 15:25:05 2008 +0000
@@ -197,6 +197,13 @@
     return m_model->getData(fromchannel, tochannel, start, count, buffers);
 }    
 
+size_t
+WritableWaveFileModel::getSummaryBlockSize(size_t desired) const
+{
+    if (!m_model) return desired;
+    return m_model->getSummaryBlockSize(desired);
+}
+
 void
 WritableWaveFileModel::getSummaries(size_t channel, size_t start, size_t count,
                                     RangeBlock &ranges,
--- a/data/model/WritableWaveFileModel.h	Thu Feb 07 12:36:59 2008 +0000
+++ b/data/model/WritableWaveFileModel.h	Thu Feb 07 15:25:05 2008 +0000
@@ -72,6 +72,8 @@
                            size_t start, size_t count,
                            float **buffer) const;
 
+    virtual size_t getSummaryBlockSize(size_t desired) const;
+
     virtual void getSummaries(size_t channel, size_t start, size_t count,
                               RangeBlock &ranges, size_t &blockSize) const;