annotate data/model/FFTModel.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 146eb9e35baa
children 2f2d282d45d0
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 "FFTModel.h"
Chris@152 17 #include "DenseTimeValueModel.h"
Chris@152 18
Chris@183 19 #include "base/Profiler.h"
Chris@183 20
Chris@152 21 #include <cassert>
Chris@152 22
Chris@152 23 FFTModel::FFTModel(const DenseTimeValueModel *model,
Chris@152 24 int channel,
Chris@152 25 WindowType windowType,
Chris@152 26 size_t windowSize,
Chris@152 27 size_t windowIncrement,
Chris@152 28 size_t fftSize,
Chris@152 29 bool polar,
Chris@152 30 size_t fillFromColumn) :
Chris@152 31 //!!! ZoomConstraint!
Chris@152 32 m_server(0),
Chris@152 33 m_xshift(0),
Chris@152 34 m_yshift(0)
Chris@152 35 {
Chris@152 36 m_server = FFTDataServer::getFuzzyInstance(model,
Chris@152 37 channel,
Chris@152 38 windowType,
Chris@152 39 windowSize,
Chris@152 40 windowIncrement,
Chris@152 41 fftSize,
Chris@152 42 polar,
Chris@152 43 fillFromColumn);
Chris@152 44
Chris@152 45 size_t xratio = windowIncrement / m_server->getWindowIncrement();
Chris@152 46 size_t yratio = m_server->getFFTSize() / fftSize;
Chris@152 47
Chris@152 48 while (xratio > 1) {
Chris@152 49 if (xratio & 0x1) {
Chris@152 50 std::cerr << "ERROR: FFTModel: Window increment ratio "
Chris@152 51 << windowIncrement << " / "
Chris@152 52 << m_server->getWindowIncrement()
Chris@152 53 << " must be a power of two" << std::endl;
Chris@152 54 assert(!(xratio & 0x1));
Chris@152 55 }
Chris@152 56 ++m_xshift;
Chris@152 57 xratio >>= 1;
Chris@152 58 }
Chris@152 59
Chris@152 60 while (yratio > 1) {
Chris@152 61 if (yratio & 0x1) {
Chris@152 62 std::cerr << "ERROR: FFTModel: FFT size ratio "
Chris@152 63 << m_server->getFFTSize() << " / " << fftSize
Chris@152 64 << " must be a power of two" << std::endl;
Chris@152 65 assert(!(yratio & 0x1));
Chris@152 66 }
Chris@152 67 ++m_yshift;
Chris@152 68 yratio >>= 1;
Chris@152 69 }
Chris@152 70 }
Chris@152 71
Chris@152 72 FFTModel::~FFTModel()
Chris@152 73 {
Chris@152 74 FFTDataServer::releaseInstance(m_server);
Chris@152 75 }
Chris@152 76
Chris@152 77 size_t
Chris@152 78 FFTModel::getSampleRate() const
Chris@152 79 {
Chris@152 80 return isOK() ? m_server->getModel()->getSampleRate() : 0;
Chris@152 81 }
Chris@152 82
Chris@152 83 void
Chris@182 84 FFTModel::getColumn(size_t x, Column &result) const
Chris@152 85 {
Chris@183 86 Profiler profiler("FFTModel::getColumn", false);
Chris@183 87
Chris@152 88 result.clear();
Chris@152 89 size_t height(getHeight());
Chris@152 90 for (size_t y = 0; y < height; ++y) {
Chris@152 91 result.push_back(const_cast<FFTModel *>(this)->getMagnitudeAt(x, y));
Chris@152 92 }
Chris@152 93 }
Chris@152 94
Chris@152 95 QString
Chris@152 96 FFTModel::getBinName(size_t n) const
Chris@152 97 {
Chris@152 98 size_t sr = getSampleRate();
Chris@152 99 if (!sr) return "";
Chris@152 100 QString name = tr("%1 Hz").arg((n * sr) / (getHeight() * 2));
Chris@152 101 return name;
Chris@152 102 }
Chris@152 103
Chris@152 104 Model *
Chris@152 105 FFTModel::clone() const
Chris@152 106 {
Chris@152 107 return new FFTModel(*this);
Chris@152 108 }
Chris@152 109
Chris@152 110 FFTModel::FFTModel(const FFTModel &model) :
Chris@152 111 DenseThreeDimensionalModel(),
Chris@152 112 m_server(model.m_server),
Chris@152 113 m_xshift(model.m_xshift),
Chris@152 114 m_yshift(model.m_yshift)
Chris@152 115 {
Chris@152 116 FFTDataServer::claimInstance(m_server);
Chris@152 117 }
Chris@152 118