annotate data/model/FFTModel.cpp @ 263:71dfc6ab3b54

* Threaded mp3/ogg file reading. Not activated yet, as it doesn't work in context (SV needs to know the duration of its main model at the outset)
author Chris Cannam
date Thu, 24 May 2007 16:20:22 +0000
parents 29b70bdaacdc
children 522f82311e4e
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@200 45 if (!m_server) return; // caller should check isOK()
Chris@200 46
Chris@152 47 size_t xratio = windowIncrement / m_server->getWindowIncrement();
Chris@152 48 size_t yratio = m_server->getFFTSize() / fftSize;
Chris@152 49
Chris@152 50 while (xratio > 1) {
Chris@152 51 if (xratio & 0x1) {
Chris@152 52 std::cerr << "ERROR: FFTModel: Window increment ratio "
Chris@152 53 << windowIncrement << " / "
Chris@152 54 << m_server->getWindowIncrement()
Chris@152 55 << " must be a power of two" << std::endl;
Chris@152 56 assert(!(xratio & 0x1));
Chris@152 57 }
Chris@152 58 ++m_xshift;
Chris@152 59 xratio >>= 1;
Chris@152 60 }
Chris@152 61
Chris@152 62 while (yratio > 1) {
Chris@152 63 if (yratio & 0x1) {
Chris@152 64 std::cerr << "ERROR: FFTModel: FFT size ratio "
Chris@152 65 << m_server->getFFTSize() << " / " << fftSize
Chris@152 66 << " must be a power of two" << std::endl;
Chris@152 67 assert(!(yratio & 0x1));
Chris@152 68 }
Chris@152 69 ++m_yshift;
Chris@152 70 yratio >>= 1;
Chris@152 71 }
Chris@152 72 }
Chris@152 73
Chris@152 74 FFTModel::~FFTModel()
Chris@152 75 {
Chris@200 76 if (m_server) FFTDataServer::releaseInstance(m_server);
Chris@152 77 }
Chris@152 78
Chris@152 79 size_t
Chris@152 80 FFTModel::getSampleRate() const
Chris@152 81 {
Chris@152 82 return isOK() ? m_server->getModel()->getSampleRate() : 0;
Chris@152 83 }
Chris@152 84
Chris@152 85 void
Chris@182 86 FFTModel::getColumn(size_t x, Column &result) const
Chris@152 87 {
Chris@183 88 Profiler profiler("FFTModel::getColumn", false);
Chris@183 89
Chris@152 90 result.clear();
Chris@152 91 size_t height(getHeight());
Chris@152 92 for (size_t y = 0; y < height; ++y) {
Chris@152 93 result.push_back(const_cast<FFTModel *>(this)->getMagnitudeAt(x, y));
Chris@152 94 }
Chris@152 95 }
Chris@152 96
Chris@152 97 QString
Chris@152 98 FFTModel::getBinName(size_t n) const
Chris@152 99 {
Chris@152 100 size_t sr = getSampleRate();
Chris@152 101 if (!sr) return "";
Chris@204 102 QString name = tr("%1 Hz").arg((n * sr) / ((getHeight()-1) * 2));
Chris@152 103 return name;
Chris@152 104 }
Chris@152 105
Chris@152 106 Model *
Chris@152 107 FFTModel::clone() const
Chris@152 108 {
Chris@152 109 return new FFTModel(*this);
Chris@152 110 }
Chris@152 111
Chris@152 112 FFTModel::FFTModel(const FFTModel &model) :
Chris@152 113 DenseThreeDimensionalModel(),
Chris@152 114 m_server(model.m_server),
Chris@152 115 m_xshift(model.m_xshift),
Chris@152 116 m_yshift(model.m_yshift)
Chris@152 117 {
Chris@152 118 FFTDataServer::claimInstance(m_server);
Chris@152 119 }
Chris@152 120