annotate data/fft/FFTFileCacheWriter.cpp @ 558:1d7ebc05157e

* Some fairly simplistic code to set up layer type properties based on RDF data about feature types (both when running transforms and when importing features from RDF files).
author Chris Cannam
date Thu, 12 Feb 2009 15:26:43 +0000
parents 107d3f3705c9
children f9cf4b49b08b
rev   line source
Chris@537 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@537 2
Chris@537 3 /*
Chris@537 4 Sonic Visualiser
Chris@537 5 An audio file viewer and annotation editor.
Chris@537 6 Centre for Digital Music, Queen Mary, University of London.
Chris@537 7 This file copyright 2006-2009 Chris Cannam and QMUL.
Chris@537 8
Chris@537 9 This program is free software; you can redistribute it and/or
Chris@537 10 modify it under the terms of the GNU General Public License as
Chris@537 11 published by the Free Software Foundation; either version 2 of the
Chris@537 12 License, or (at your option) any later version. See the file
Chris@537 13 COPYING included with this distribution for more information.
Chris@537 14 */
Chris@537 15
Chris@537 16 #include "FFTFileCacheWriter.h"
Chris@537 17
Chris@537 18 #include "fileio/MatrixFile.h"
Chris@537 19
Chris@537 20 #include "base/Profiler.h"
Chris@537 21 #include "base/Thread.h"
Chris@537 22 #include "base/Exceptions.h"
Chris@537 23
Chris@537 24 #include <iostream>
Chris@537 25
Chris@537 26 //#define DEBUG_FFT_FILE_CACHE_WRITER 1
Chris@537 27
Chris@537 28
Chris@537 29 // The underlying matrix has height (m_height * 2 + 1). In each
Chris@537 30 // column we store magnitude at [0], [2] etc and phase at [1], [3]
Chris@537 31 // etc, and then store the normalization factor (maximum magnitude) at
Chris@537 32 // [m_height * 2]. In compact mode, the factor takes two cells.
Chris@537 33
Chris@537 34 FFTFileCacheWriter::FFTFileCacheWriter(QString fileBase,
Chris@537 35 FFTCache::StorageType storageType,
Chris@537 36 size_t width, size_t height) :
Chris@537 37 m_writebuf(0),
Chris@537 38 m_fileBase(fileBase),
Chris@537 39 m_storageType(storageType),
Chris@537 40 m_factorSize(storageType == FFTCache::Compact ? 2 : 1),
Chris@537 41 m_mfc(new MatrixFile
Chris@537 42 (fileBase, MatrixFile::WriteOnly,
Chris@537 43 storageType == FFTCache::Compact ? sizeof(uint16_t) : sizeof(float),
Chris@537 44 width, height * 2 + m_factorSize))
Chris@537 45 {
Chris@537 46 std::cerr << "FFTFileCacheWriter: storage type is " << (storageType == FFTCache::Compact ? "Compact" : storageType == FFTCache::Polar ? "Polar" : "Rectangular") << ", size " << width << "x" << height << std::endl;
Chris@550 47 m_mfc->setAutoClose(true);
Chris@537 48 m_writebuf = new char[(height * 2 + m_factorSize) * m_mfc->getCellSize()];
Chris@537 49 }
Chris@537 50
Chris@537 51 FFTFileCacheWriter::~FFTFileCacheWriter()
Chris@537 52 {
Chris@537 53 if (m_writebuf) delete[] m_writebuf;
Chris@537 54 delete m_mfc;
Chris@537 55 }
Chris@537 56
Chris@537 57 QString
Chris@537 58 FFTFileCacheWriter::getFileBase() const
Chris@537 59 {
Chris@537 60 return m_fileBase;
Chris@537 61 }
Chris@537 62
Chris@537 63 size_t
Chris@537 64 FFTFileCacheWriter::getWidth() const
Chris@537 65 {
Chris@537 66 return m_mfc->getWidth();
Chris@537 67 }
Chris@537 68
Chris@537 69 size_t
Chris@537 70 FFTFileCacheWriter::getHeight() const
Chris@537 71 {
Chris@537 72 size_t mh = m_mfc->getHeight();
Chris@537 73 if (mh > m_factorSize) return (mh - m_factorSize) / 2;
Chris@537 74 else return 0;
Chris@537 75 }
Chris@537 76
Chris@550 77 bool
Chris@550 78 FFTFileCacheWriter::haveSetColumnAt(size_t x) const
Chris@550 79 {
Chris@550 80 return m_mfc->haveSetColumnAt(x);
Chris@550 81 }
Chris@550 82
Chris@537 83 void
Chris@537 84 FFTFileCacheWriter::setColumnAt(size_t x, float *mags, float *phases, float factor)
Chris@537 85 {
Chris@537 86 size_t h = getHeight();
Chris@537 87
Chris@537 88 switch (m_storageType) {
Chris@537 89
Chris@537 90 case FFTCache::Compact:
Chris@537 91 for (size_t y = 0; y < h; ++y) {
Chris@537 92 ((uint16_t *)m_writebuf)[y * 2] = uint16_t((mags[y] / factor) * 65535.0);
Chris@537 93 ((uint16_t *)m_writebuf)[y * 2 + 1] = uint16_t(int16_t((phases[y] * 32767) / M_PI));
Chris@537 94 }
Chris@537 95 break;
Chris@537 96
Chris@537 97 case FFTCache::Rectangular:
Chris@537 98 for (size_t y = 0; y < h; ++y) {
Chris@537 99 ((float *)m_writebuf)[y * 2] = mags[y] * cosf(phases[y]);
Chris@537 100 ((float *)m_writebuf)[y * 2 + 1] = mags[y] * sinf(phases[y]);
Chris@537 101 }
Chris@537 102 break;
Chris@537 103
Chris@537 104 case FFTCache::Polar:
Chris@537 105 for (size_t y = 0; y < h; ++y) {
Chris@537 106 ((float *)m_writebuf)[y * 2] = mags[y];
Chris@537 107 ((float *)m_writebuf)[y * 2 + 1] = phases[y];
Chris@537 108 }
Chris@537 109 break;
Chris@537 110 }
Chris@537 111
Chris@537 112 static float maxFactor = 0;
Chris@537 113 if (factor > maxFactor) maxFactor = factor;
Chris@537 114 #ifdef DEBUG_FFT_FILE_CACHE_WRITER
Chris@537 115 std::cerr << "Column " << x << ": normalization factor: " << factor << ", max " << maxFactor << " (height " << getHeight() << ")" << std::endl;
Chris@537 116 #endif
Chris@537 117
Chris@537 118 setNormalizationFactorToWritebuf(factor);
Chris@537 119
Chris@537 120 m_mfc->setColumnAt(x, m_writebuf);
Chris@537 121 }
Chris@537 122
Chris@537 123 void
Chris@537 124 FFTFileCacheWriter::setColumnAt(size_t x, float *real, float *imag)
Chris@537 125 {
Chris@537 126 size_t h = getHeight();
Chris@537 127
Chris@537 128 float factor = 0.0f;
Chris@537 129
Chris@537 130 switch (m_storageType) {
Chris@537 131
Chris@537 132 case FFTCache::Compact:
Chris@537 133 for (size_t y = 0; y < h; ++y) {
Chris@537 134 float mag = sqrtf(real[y] * real[y] + imag[y] * imag[y]);
Chris@537 135 if (mag > factor) factor = mag;
Chris@537 136 }
Chris@537 137 for (size_t y = 0; y < h; ++y) {
Chris@537 138 float mag = sqrtf(real[y] * real[y] + imag[y] * imag[y]);
Chris@537 139 float phase = atan2f(imag[y], real[y]);
Chris@537 140 ((uint16_t *)m_writebuf)[y * 2] = uint16_t((mag / factor) * 65535.0);
Chris@537 141 ((uint16_t *)m_writebuf)[y * 2 + 1] = uint16_t(int16_t((phase * 32767) / M_PI));
Chris@537 142 }
Chris@537 143 break;
Chris@537 144
Chris@537 145 case FFTCache::Rectangular:
Chris@537 146 for (size_t y = 0; y < h; ++y) {
Chris@537 147 ((float *)m_writebuf)[y * 2] = real[y];
Chris@537 148 ((float *)m_writebuf)[y * 2 + 1] = imag[y];
Chris@537 149 float mag = sqrtf(real[y] * real[y] + imag[y] * imag[y]);
Chris@537 150 if (mag > factor) factor = mag;
Chris@537 151 }
Chris@537 152 break;
Chris@537 153
Chris@537 154 case FFTCache::Polar:
Chris@537 155 for (size_t y = 0; y < h; ++y) {
Chris@537 156 float mag = sqrtf(real[y] * real[y] + imag[y] * imag[y]);
Chris@537 157 if (mag > factor) factor = mag;
Chris@537 158 ((float *)m_writebuf)[y * 2] = mag;
Chris@537 159 float phase = atan2f(imag[y], real[y]);
Chris@537 160 ((float *)m_writebuf)[y * 2 + 1] = phase;
Chris@537 161 }
Chris@537 162 break;
Chris@537 163 }
Chris@537 164
Chris@537 165 static float maxFactor = 0;
Chris@537 166 if (factor > maxFactor) maxFactor = factor;
Chris@537 167 #ifdef DEBUG_FFT_FILE_CACHE_WRITER
Chris@537 168 std::cerr << "[RI] Column " << x << ": normalization factor: " << factor << ", max " << maxFactor << " (height " << getHeight() << ")" << std::endl;
Chris@537 169 #endif
Chris@537 170
Chris@537 171 setNormalizationFactorToWritebuf(factor);
Chris@537 172
Chris@537 173 m_mfc->setColumnAt(x, m_writebuf);
Chris@537 174 }
Chris@537 175
Chris@537 176 size_t
Chris@537 177 FFTFileCacheWriter::getCacheSize(size_t width, size_t height,
Chris@537 178 FFTCache::StorageType type)
Chris@537 179 {
Chris@537 180 return (height * 2 + (type == FFTCache::Compact ? 2 : 1)) * width *
Chris@537 181 (type == FFTCache::Compact ? sizeof(uint16_t) : sizeof(float)) +
Chris@537 182 2 * sizeof(size_t); // matrix file header size
Chris@537 183 }
Chris@537 184
Chris@537 185 void
Chris@537 186 FFTFileCacheWriter::allColumnsWritten()
Chris@537 187 {
Chris@537 188 #ifdef DEBUG_FFT_FILE_CACHE_WRITER
Chris@537 189 std::cerr << "FFTFileCacheWriter::allColumnsWritten" << std::endl;
Chris@537 190 #endif
Chris@537 191 m_mfc->close();
Chris@537 192 }
Chris@537 193