annotate data/fft/FFTCache.cpp @ 154:6ec58bb8f729

* Suspend/resume fft data server write activity while reading from a server to repaint the spectrogram display. Makes a significant improvement to the otherwise dreadful responsiveness of spectrogram display.
author Chris Cannam
date Thu, 03 Aug 2006 12:42:15 +0000
parents 21792a550ec9
children
rev   line source
Chris@152 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@152 2
Chris@152 3 /*
Chris@152 4 Sonic Visualiser
Chris@152 5 An audio file viewer and annotation editor.
Chris@152 6 Centre for Digital Music, Queen Mary, University of London.
Chris@152 7 This file copyright 2006 Chris Cannam.
Chris@152 8
Chris@152 9 This program is free software; you can redistribute it and/or
Chris@152 10 modify it under the terms of the GNU General Public License as
Chris@152 11 published by the Free Software Foundation; either version 2 of the
Chris@152 12 License, or (at your option) any later version. See the file
Chris@152 13 COPYING included with this distribution for more information.
Chris@152 14 */
Chris@152 15
Chris@152 16 #include "FFTCache.h"
Chris@152 17 #include "system/System.h"
Chris@152 18
Chris@152 19 #include <iostream>
Chris@152 20
Chris@152 21 //!!! This class is a work in progress -- it does only as much as we
Chris@152 22 // need for the current SpectrogramLayer. Slated for substantial
Chris@152 23 // refactoring and extension.
Chris@152 24
Chris@152 25 FFTMemoryCache::FFTMemoryCache() :
Chris@152 26 m_width(0),
Chris@152 27 m_height(0),
Chris@152 28 m_magnitude(0),
Chris@152 29 m_phase(0),
Chris@152 30 m_factor(0)
Chris@152 31 {
Chris@152 32 }
Chris@152 33
Chris@152 34 FFTMemoryCache::~FFTMemoryCache()
Chris@152 35 {
Chris@152 36 std::cerr << "FFTMemoryCache[" << this << "]::~Cache" << std::endl;
Chris@152 37
Chris@152 38 for (size_t i = 0; i < m_width; ++i) {
Chris@152 39 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
Chris@152 40 if (m_phase && m_phase[i]) free(m_phase[i]);
Chris@152 41 }
Chris@152 42
Chris@152 43 if (m_magnitude) free(m_magnitude);
Chris@152 44 if (m_phase) free(m_phase);
Chris@152 45 if (m_factor) free(m_factor);
Chris@152 46 }
Chris@152 47
Chris@152 48 void
Chris@152 49 FFTMemoryCache::resize(size_t width, size_t height)
Chris@152 50 {
Chris@152 51 std::cerr << "FFTMemoryCache[" << this << "]::resize(" << width << "x" << height << " = " << width*height << ")" << std::endl;
Chris@152 52
Chris@152 53 if (m_width == width && m_height == height) return;
Chris@152 54
Chris@152 55 resize(m_magnitude, width, height);
Chris@152 56 resize(m_phase, width, height);
Chris@152 57
Chris@152 58 m_factor = (float *)realloc(m_factor, width * sizeof(float));
Chris@152 59
Chris@152 60 m_width = width;
Chris@152 61 m_height = height;
Chris@152 62
Chris@152 63 std::cerr << "done, width = " << m_width << " height = " << m_height << std::endl;
Chris@152 64 }
Chris@152 65
Chris@152 66 void
Chris@152 67 FFTMemoryCache::resize(uint16_t **&array, size_t width, size_t height)
Chris@152 68 {
Chris@152 69 for (size_t i = width; i < m_width; ++i) {
Chris@152 70 free(array[i]);
Chris@152 71 }
Chris@152 72
Chris@152 73 if (width != m_width) {
Chris@152 74 array = (uint16_t **)realloc(array, width * sizeof(uint16_t *));
Chris@152 75 if (!array) throw std::bad_alloc();
Chris@152 76 MUNLOCK(array, width * sizeof(uint16_t *));
Chris@152 77 }
Chris@152 78
Chris@152 79 for (size_t i = m_width; i < width; ++i) {
Chris@152 80 array[i] = 0;
Chris@152 81 }
Chris@152 82
Chris@152 83 for (size_t i = 0; i < width; ++i) {
Chris@152 84 array[i] = (uint16_t *)realloc(array[i], height * sizeof(uint16_t));
Chris@152 85 if (!array[i]) throw std::bad_alloc();
Chris@152 86 MUNLOCK(array[i], height * sizeof(uint16_t));
Chris@152 87 }
Chris@152 88 }
Chris@152 89
Chris@152 90 void
Chris@152 91 FFTMemoryCache::reset()
Chris@152 92 {
Chris@152 93 for (size_t x = 0; x < m_width; ++x) {
Chris@152 94 for (size_t y = 0; y < m_height; ++y) {
Chris@152 95 m_magnitude[x][y] = 0;
Chris@152 96 m_phase[x][y] = 0;
Chris@152 97 }
Chris@152 98 m_factor[x] = 1.0;
Chris@152 99 }
Chris@152 100 }
Chris@152 101
Chris@152 102 void
Chris@152 103 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
Chris@152 104 {
Chris@152 105 float max = 0.0;
Chris@152 106
Chris@152 107 for (size_t y = 0; y < m_height; ++y) {
Chris@152 108 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
Chris@152 109 float phase = atan2f(imags[y], reals[y]);
Chris@152 110 phase = princargf(phase);
Chris@152 111 reals[y] = mag;
Chris@152 112 imags[y] = phase;
Chris@152 113 if (mag > max) max = mag;
Chris@152 114 }
Chris@152 115
Chris@152 116 setColumnAt(x, reals, imags, max);
Chris@152 117 }
Chris@152 118