Cache FFT result

This commit is contained in:
Mike Walters
2015-09-06 01:38:25 +01:00
parent 4eb33aef1e
commit b6528bdb7c
2 changed files with 42 additions and 8 deletions

View File

@@ -62,12 +62,21 @@ void Spectrogram::paintEvent(QPaintEvent *event)
if (inputSource != nullptr) {
int height = rect.height();
float *line = (float*)malloc(fftSize * sizeof(float));
int tileLine = linesPerTile();
QImage image(fftSize, height, QImage::Format_RGB32);
float *tile;
for (int y = 0; y < height; y++) {
getLine(line, rect.y() + y);
if (tileLine >= linesPerTile()) {
int tileId = (rect.y() + y) / linesPerTile();
tile = getTile(tileId);
// Handle case where we want to draw from part-way through the first tile
tileLine = (rect.y() + y) - (tileId * linesPerTile());
}
float *line = &tile[tileLine * fftSize];
for (int x = 0; x < fftSize; x++) {
float powerRange = std::abs(int(powerMin - powerMax)); // Cast to remove overload ambiguity
float normPower = (line[x] - powerMax) * -1.0f / powerRange;
@@ -75,24 +84,41 @@ void Spectrogram::paintEvent(QPaintEvent *event)
image.setPixel(x, y, colormap[(uint8_t)(normPower * (256 - 1))]);
}
tileLine++;
}
QPixmap pixmap = QPixmap::fromImage(image);
painter.drawPixmap(QRect(0, rect.y(), fftSize, height), pixmap);
free(line);
paintTimeAxis(&painter, rect);
}
qDebug() << "Paint: " << timer.elapsed() << "ms";
}
void Spectrogram::getLine(float *dest, int y)
float* Spectrogram::getTile(off_t tile)
{
auto iter = fftCache.find(qMakePair(zoomLevel, tile));
if (iter != fftCache.end())
return iter.value();
float *dest = new float[tileSize];
float *ptr = dest;
off_t sample = tile * linesPerTile() * getStride();
while ((ptr - dest) < tileSize) {
getLine(ptr, sample);
sample += getStride();
ptr += fftSize;
}
fftCache.insert(qMakePair(zoomLevel, tile), dest);
return dest;
}
void Spectrogram::getLine(float *dest, off_t sample)
{
if (inputSource && fft) {
fftwf_complex buffer[fftSize];
inputSource->getSamples(buffer, y * getStride(), fftSize);
inputSource->getSamples(buffer, sample, fftSize);
for (int i = 0; i < fftSize; i++) {
buffer[i][0] *= window[i];
@@ -189,3 +215,7 @@ QString Spectrogram::sampleToTime(off_t sample)
{
return QString::number((float)sample / sampleRate).append("s");
}
int Spectrogram::linesPerTile() {
return tileSize / fftSize;
}