Chris@152: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@152: Chris@152: /* Chris@152: Sonic Visualiser Chris@152: An audio file viewer and annotation editor. Chris@152: Centre for Digital Music, Queen Mary, University of London. Chris@152: This file copyright 2006 Chris Cannam. Chris@152: Chris@152: This program is free software; you can redistribute it and/or Chris@152: modify it under the terms of the GNU General Public License as Chris@152: published by the Free Software Foundation; either version 2 of the Chris@152: License, or (at your option) any later version. See the file Chris@152: COPYING included with this distribution for more information. Chris@152: */ Chris@152: Chris@152: #include "FFTModel.h" Chris@152: #include "DenseTimeValueModel.h" Chris@152: Chris@183: #include "base/Profiler.h" Chris@183: Chris@152: #include Chris@152: Chris@152: FFTModel::FFTModel(const DenseTimeValueModel *model, Chris@152: int channel, Chris@152: WindowType windowType, Chris@152: size_t windowSize, Chris@152: size_t windowIncrement, Chris@152: size_t fftSize, Chris@152: bool polar, Chris@152: size_t fillFromColumn) : Chris@152: //!!! ZoomConstraint! Chris@152: m_server(0), Chris@152: m_xshift(0), Chris@152: m_yshift(0) Chris@152: { Chris@152: m_server = FFTDataServer::getFuzzyInstance(model, Chris@152: channel, Chris@152: windowType, Chris@152: windowSize, Chris@152: windowIncrement, Chris@152: fftSize, Chris@152: polar, Chris@152: fillFromColumn); Chris@152: Chris@152: size_t xratio = windowIncrement / m_server->getWindowIncrement(); Chris@152: size_t yratio = m_server->getFFTSize() / fftSize; Chris@152: Chris@152: while (xratio > 1) { Chris@152: if (xratio & 0x1) { Chris@152: std::cerr << "ERROR: FFTModel: Window increment ratio " Chris@152: << windowIncrement << " / " Chris@152: << m_server->getWindowIncrement() Chris@152: << " must be a power of two" << std::endl; Chris@152: assert(!(xratio & 0x1)); Chris@152: } Chris@152: ++m_xshift; Chris@152: xratio >>= 1; Chris@152: } Chris@152: Chris@152: while (yratio > 1) { Chris@152: if (yratio & 0x1) { Chris@152: std::cerr << "ERROR: FFTModel: FFT size ratio " Chris@152: << m_server->getFFTSize() << " / " << fftSize Chris@152: << " must be a power of two" << std::endl; Chris@152: assert(!(yratio & 0x1)); Chris@152: } Chris@152: ++m_yshift; Chris@152: yratio >>= 1; Chris@152: } Chris@152: } Chris@152: Chris@152: FFTModel::~FFTModel() Chris@152: { Chris@152: FFTDataServer::releaseInstance(m_server); Chris@152: } Chris@152: Chris@152: size_t Chris@152: FFTModel::getSampleRate() const Chris@152: { Chris@152: return isOK() ? m_server->getModel()->getSampleRate() : 0; Chris@152: } Chris@152: Chris@152: void Chris@182: FFTModel::getColumn(size_t x, Column &result) const Chris@152: { Chris@183: Profiler profiler("FFTModel::getColumn", false); Chris@183: Chris@152: result.clear(); Chris@152: size_t height(getHeight()); Chris@152: for (size_t y = 0; y < height; ++y) { Chris@152: result.push_back(const_cast(this)->getMagnitudeAt(x, y)); Chris@152: } Chris@152: } Chris@152: Chris@152: QString Chris@152: FFTModel::getBinName(size_t n) const Chris@152: { Chris@152: size_t sr = getSampleRate(); Chris@152: if (!sr) return ""; Chris@152: QString name = tr("%1 Hz").arg((n * sr) / (getHeight() * 2)); Chris@152: return name; Chris@152: } Chris@152: Chris@152: Model * Chris@152: FFTModel::clone() const Chris@152: { Chris@152: return new FFTModel(*this); Chris@152: } Chris@152: Chris@152: FFTModel::FFTModel(const FFTModel &model) : Chris@152: DenseThreeDimensionalModel(), Chris@152: m_server(model.m_server), Chris@152: m_xshift(model.m_xshift), Chris@152: m_yshift(model.m_yshift) Chris@152: { Chris@152: FFTDataServer::claimInstance(m_server); Chris@152: } Chris@152: