annotate data/fft/FFTMemoryCache.cpp @ 184:5a916fee6d2d

* Handle generator transforms (plugins whose channel count isn't dependent on number of audio inputs, as they have none) * Be less keen to suspend writing FFT data in spectrogram repaint -- only do it if we find we actually need to query the FFT data (i.e. we aren't repainting an area that hasn't been generated at all yet)
author Chris Cannam
date Tue, 10 Oct 2006 19:04:57 +0000
parents b23eea68357e
children ff46f251139e
rev   line source
Chris@159 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@159 2
Chris@159 3 /*
Chris@159 4 Sonic Visualiser
Chris@159 5 An audio file viewer and annotation editor.
Chris@159 6 Centre for Digital Music, Queen Mary, University of London.
Chris@159 7 This file copyright 2006 Chris Cannam.
Chris@159 8
Chris@159 9 This program is free software; you can redistribute it and/or
Chris@159 10 modify it under the terms of the GNU General Public License as
Chris@159 11 published by the Free Software Foundation; either version 2 of the
Chris@159 12 License, or (at your option) any later version. See the file
Chris@159 13 COPYING included with this distribution for more information.
Chris@159 14 */
Chris@159 15
Chris@159 16 #include "FFTMemoryCache.h"
Chris@159 17 #include "system/System.h"
Chris@159 18
Chris@159 19 #include <iostream>
Chris@159 20
Chris@159 21 FFTMemoryCache::FFTMemoryCache() :
Chris@159 22 m_width(0),
Chris@159 23 m_height(0),
Chris@159 24 m_magnitude(0),
Chris@159 25 m_phase(0),
Chris@159 26 m_factor(0)
Chris@159 27 {
Chris@159 28 }
Chris@159 29
Chris@159 30 FFTMemoryCache::~FFTMemoryCache()
Chris@159 31 {
Chris@159 32 std::cerr << "FFTMemoryCache[" << this << "]::~Cache" << std::endl;
Chris@159 33
Chris@159 34 for (size_t i = 0; i < m_width; ++i) {
Chris@159 35 if (m_magnitude && m_magnitude[i]) free(m_magnitude[i]);
Chris@159 36 if (m_phase && m_phase[i]) free(m_phase[i]);
Chris@159 37 }
Chris@159 38
Chris@159 39 if (m_magnitude) free(m_magnitude);
Chris@159 40 if (m_phase) free(m_phase);
Chris@159 41 if (m_factor) free(m_factor);
Chris@159 42 }
Chris@159 43
Chris@159 44 void
Chris@159 45 FFTMemoryCache::resize(size_t width, size_t height)
Chris@159 46 {
Chris@159 47 std::cerr << "FFTMemoryCache[" << this << "]::resize(" << width << "x" << height << " = " << width*height << ")" << std::endl;
Chris@159 48
Chris@159 49 if (m_width == width && m_height == height) return;
Chris@159 50
Chris@159 51 resize(m_magnitude, width, height);
Chris@159 52 resize(m_phase, width, height);
Chris@159 53 m_colset.resize(width);
Chris@159 54
Chris@159 55 m_factor = (float *)realloc(m_factor, width * sizeof(float));
Chris@159 56
Chris@159 57 m_width = width;
Chris@159 58 m_height = height;
Chris@159 59
Chris@159 60 std::cerr << "done, width = " << m_width << " height = " << m_height << std::endl;
Chris@159 61 }
Chris@159 62
Chris@159 63 void
Chris@159 64 FFTMemoryCache::resize(uint16_t **&array, size_t width, size_t height)
Chris@159 65 {
Chris@159 66 for (size_t i = width; i < m_width; ++i) {
Chris@159 67 free(array[i]);
Chris@159 68 }
Chris@159 69
Chris@159 70 if (width != m_width) {
Chris@159 71 array = (uint16_t **)realloc(array, width * sizeof(uint16_t *));
Chris@159 72 if (!array) throw std::bad_alloc();
Chris@159 73 MUNLOCK(array, width * sizeof(uint16_t *));
Chris@159 74 }
Chris@159 75
Chris@159 76 for (size_t i = m_width; i < width; ++i) {
Chris@159 77 array[i] = 0;
Chris@159 78 }
Chris@159 79
Chris@159 80 for (size_t i = 0; i < width; ++i) {
Chris@159 81 array[i] = (uint16_t *)realloc(array[i], height * sizeof(uint16_t));
Chris@159 82 if (!array[i]) throw std::bad_alloc();
Chris@159 83 MUNLOCK(array[i], height * sizeof(uint16_t));
Chris@159 84 }
Chris@159 85 }
Chris@159 86
Chris@159 87 void
Chris@159 88 FFTMemoryCache::reset()
Chris@159 89 {
Chris@159 90 for (size_t x = 0; x < m_width; ++x) {
Chris@159 91 for (size_t y = 0; y < m_height; ++y) {
Chris@159 92 m_magnitude[x][y] = 0;
Chris@159 93 m_phase[x][y] = 0;
Chris@159 94 }
Chris@159 95 m_factor[x] = 1.0;
Chris@159 96 }
Chris@159 97 }
Chris@159 98
Chris@159 99 void
Chris@159 100 FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
Chris@159 101 {
Chris@159 102 float max = 0.0;
Chris@159 103
Chris@159 104 for (size_t y = 0; y < m_height; ++y) {
Chris@159 105 float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
Chris@159 106 float phase = atan2f(imags[y], reals[y]);
Chris@159 107 phase = princargf(phase);
Chris@159 108 reals[y] = mag;
Chris@159 109 imags[y] = phase;
Chris@159 110 if (mag > max) max = mag;
Chris@159 111 }
Chris@159 112
Chris@159 113 setColumnAt(x, reals, imags, max);
Chris@159 114 }
Chris@159 115
Chris@170 116 size_t
Chris@170 117 FFTMemoryCache::getCacheSize(size_t width, size_t height)
Chris@170 118 {
Chris@170 119 return (height * 2 + 1) * width * sizeof(uint16_t);
Chris@170 120 }
Chris@170 121