# HG changeset patch # User Chris Cannam # Date 1210944427 0 # Node ID 9c7ebf2cd95616de4f6af336b6f2fd6e9cd10749 # Parent 6075c90744d49cf28ecd26fc80f9c024d0c612a9 * Halve space requirements for range (waveform peak) caches diff -r 6075c90744d4 -r 9c7ebf2cd956 data/model/RangeSummarisableTimeValueModel.h --- a/data/model/RangeSummarisableTimeValueModel.h Fri May 09 12:39:02 2008 +0000 +++ b/data/model/RangeSummarisableTimeValueModel.h Fri May 16 13:27:07 2008 +0000 @@ -35,18 +35,65 @@ public: RangeSummarisableTimeValueModel() { } - struct Range +#define RANGE_USE_SHORT 1 +#ifdef RANGE_USE_SHORT + class Range { - float min; - float max; - float absmean; + public: Range() : - min(0.f), max(0.f), absmean(0.f) { } + m_min(0), m_max(0), m_absmean(0) { } Range(const Range &r) : - min(r.min), max(r.max), absmean(r.absmean) { } - Range(float min_, float max_, float absmean_) : - min(min_), max(max_), absmean(absmean_) { } + m_min(r.m_min), m_max(r.m_max), m_absmean(r.m_absmean) { } + Range(float min, float max, float absmean) + { setMin(min); setMax(max); setAbsmean(absmean); } + + float min() const { return i2f(m_min); } + float max() const { return i2f(m_max); } + float absmean() const { return i2f(m_absmean); } + + void setMin(float min) { m_min = f2i(min); } + void setMax(float max) { m_max = f2i(max); } + void setAbsmean(float absmean) { m_absmean = f2i(absmean); } + + private: + static inline int16_t f2i(float f) { + if (f > 1.f) f = 1.f; + if (f < -1.f) f = -1.f; + return int16_t(f * 32767.f); + } + static inline float i2f(int16_t i) { + return float(i) / 32767.f; + } + + int16_t m_min; + int16_t m_max; + int16_t m_absmean; }; +#else + class Range + { + public: + Range() : + m_min(0.f), m_max(0.f), m_absmean(0.f) { } + Range(const Range &r) : + m_min(r.m_min), m_max(r.m_max), m_absmean(r.m_absmean) { } + Range(float min, float max, float absmean) : + m_min(min), m_max(max), m_absmean(absmean) { } + + float min() const { return m_min; } + float max() const { return m_max; } + float absmean() const { return m_absmean; } + + void setMin(float min) { m_min = min; } + void setMax(float max) { m_max = max; } + void setAbsmean(float absmean) { m_absmean = absmean; } + + private: + float m_min; + float m_max; + float m_absmean; + }; +#endif typedef std::vector RangeBlock; diff -r 6075c90744d4 -r 9c7ebf2cd956 data/model/WaveFileModel.cpp --- a/data/model/WaveFileModel.cpp Fri May 09 12:39:02 2008 +0000 +++ b/data/model/WaveFileModel.cpp Fri May 16 13:27:07 2008 +0000 @@ -502,9 +502,9 @@ if (index >= cache.size()) break; const Range &range = cache[index]; - if (range.max > max || got == 0) max = range.max; - if (range.min < min || got == 0) min = range.min; - total += range.absmean; + if (range.max() > max || got == 0) max = range.max(); + if (range.min() < min || got == 0) min = range.min(); + total += range.absmean(); ++i; ++got; @@ -555,25 +555,25 @@ RangeBlock ranges; getSummaries(channel, blockStart, blockEnd - blockStart, ranges, blockSize); for (size_t i = 0; i < ranges.size(); ++i) { - if (first || ranges[i].min < range.min) range.min = ranges[i].min; - if (first || ranges[i].max > range.max) range.max = ranges[i].max; - if (first || ranges[i].absmean < range.absmean) range.absmean = ranges[i].absmean; + if (first || ranges[i].min() < range.min()) range.setMin(ranges[i].min()); + if (first || ranges[i].max() > range.max()) range.setMax(ranges[i].max()); + if (first || ranges[i].absmean() < range.absmean()) range.setAbsmean(ranges[i].absmean()); first = false; } } if (blockStart > start) { Range startRange = getSummary(channel, start, blockStart - start); - range.min = std::min(range.min, startRange.min); - range.max = std::max(range.max, startRange.max); - range.absmean = std::min(range.absmean, startRange.absmean); + range.setMin(std::min(range.min(), startRange.min())); + range.setMax(std::max(range.max(), startRange.max())); + range.setAbsmean(std::min(range.absmean(), startRange.absmean())); } if (blockEnd < start + count) { Range endRange = getSummary(channel, blockEnd, start + count - blockEnd); - range.min = std::min(range.min, endRange.min); - range.max = std::max(range.max, endRange.max); - range.absmean = std::min(range.absmean, endRange.absmean); + range.setMin(std::min(range.min(), endRange.min())); + range.setMax(std::max(range.max(), endRange.max())); + range.setAbsmean(std::min(range.absmean(), endRange.absmean())); } return range; @@ -663,6 +663,7 @@ } Range *range = new Range[2 * channels]; + float *means = new float[2 * channels]; size_t count[2]; count[0] = count[1] = 0; @@ -698,13 +699,14 @@ size_t rangeIndex = ch * 2 + ct; - if (sample > range[rangeIndex].max || count[ct] == 0) { - range[rangeIndex].max = sample; + if (sample > range[rangeIndex].max() || count[ct] == 0) { + range[rangeIndex].setMax(sample); } - if (sample < range[rangeIndex].min || count[ct] == 0) { - range[rangeIndex].min = sample; + if (sample < range[rangeIndex].min() || count[ct] == 0) { + range[rangeIndex].setMin(sample); } - range[rangeIndex].absmean += fabsf(sample); + + means[rangeIndex] += fabsf(sample); } } @@ -713,10 +715,11 @@ for (size_t ct = 0; ct < 2; ++ct) { if (++count[ct] == cacheBlockSize[ct]) { - + for (size_t ch = 0; ch < size_t(channels); ++ch) { size_t rangeIndex = ch * 2 + ct; - range[rangeIndex].absmean /= count[ct]; + means[rangeIndex] /= count[ct]; + range[rangeIndex].setAbsmean(means[rangeIndex]); m_model.m_cache[ct].push_back(range[rangeIndex]); range[rangeIndex] = Range(); } @@ -753,7 +756,8 @@ for (size_t ch = 0; ch < size_t(channels); ++ch) { size_t rangeIndex = ch * 2 + ct; - range[rangeIndex].absmean /= count[ct]; + means[rangeIndex] /= count[ct]; + range[rangeIndex].setAbsmean(means[rangeIndex]); m_model.m_cache[ct].push_back(range[rangeIndex]); range[rangeIndex] = Range(); } @@ -766,6 +770,7 @@ } } + delete[] means; delete[] range; m_fillExtent = m_frameCount;