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