Chris@133: Chris@133: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@133: Chris@133: /* Chris@133: Sonic Visualiser Chris@133: An audio file viewer and annotation editor. Chris@133: Centre for Digital Music, Queen Mary, University of London. Chris@133: This file copyright 2006 Chris Cannam. Chris@133: Chris@133: This program is free software; you can redistribute it and/or Chris@133: modify it under the terms of the GNU General Public License as Chris@133: published by the Free Software Foundation; either version 2 of the Chris@133: License, or (at your option) any later version. See the file Chris@133: COPYING included with this distribution for more information. Chris@133: */ Chris@133: Chris@133: #include "SpectrumLayer.h" Chris@133: Chris@133: #include "data/model/FFTModel.h" Chris@133: #include "view/View.h" Chris@133: Chris@133: #include Chris@133: #include Chris@133: Chris@133: SpectrumLayer::SpectrumLayer() : Chris@133: m_model(0), Chris@133: m_fft(0), Chris@133: m_colour(Qt::blue) Chris@133: { Chris@133: } Chris@133: Chris@133: SpectrumLayer::~SpectrumLayer() Chris@133: { Chris@133: delete m_fft; Chris@133: } Chris@133: Chris@133: void Chris@133: SpectrumLayer::setModel(DenseTimeValueModel *model) Chris@133: { Chris@133: m_model = model; Chris@133: delete m_fft; Chris@133: m_fft = new FFTModel(m_model, Chris@133: -1, Chris@133: HanningWindow, Chris@133: 1024, Chris@133: 256, Chris@133: 1024, Chris@133: true); Chris@133: m_fft->resume(); Chris@133: } Chris@133: Chris@133: void Chris@133: SpectrumLayer::paint(View *v, QPainter &paint, QRect rect) const Chris@133: { Chris@133: if (!m_fft) return; Chris@133: Chris@133: int fftSize = 1024; //!!! ... Chris@133: int windowIncrement = 256; Chris@133: int windowSize = 1024; Chris@133: Chris@133: size_t f = v->getCentreFrame(); Chris@133: Chris@133: int w = (v->width() * 2) / 3; Chris@133: int xorigin = (v->width() / 2) - (w / 2); Chris@133: Chris@133: int h = (v->height() * 2) / 3; Chris@133: int yorigin = (v->height() / 2) + (h / 2); Chris@133: Chris@133: size_t column = f / windowIncrement; Chris@133: Chris@133: paint.save(); Chris@133: paint.setPen(m_colour); Chris@133: paint.setRenderHint(QPainter::Antialiasing, false); Chris@133: Chris@133: QPainterPath path; Chris@133: float thresh = -80.f; Chris@133: Chris@133: for (size_t bin = 0; bin < m_fft->getHeight(); ++bin) { Chris@133: Chris@133: float mag = m_fft->getMagnitudeAt(column, bin); Chris@133: float db = thresh; Chris@133: if (mag > 0.f) db = 10.f * log10f(mag); Chris@133: if (db < thresh) db = thresh; Chris@133: float val = (db - thresh) / -thresh; Chris@133: float x = xorigin + (float(w) * bin) / m_fft->getHeight(); Chris@133: float y = yorigin - (float(h) * val); Chris@133: Chris@133: if (bin == 0) { Chris@133: path.moveTo(x, y); Chris@133: } else { Chris@133: path.lineTo(x, y); Chris@133: } Chris@133: } Chris@133: Chris@133: paint.drawPath(path); Chris@133: // paint.setRenderHint(QPainter::Antialiasing, false); Chris@133: paint.restore(); Chris@133: Chris@133: } Chris@133: Chris@133: void Chris@133: SpectrumLayer::setProperties(const QXmlAttributes &attr) Chris@133: { Chris@133: } Chris@133: Chris@133: bool Chris@133: SpectrumLayer::getValueExtents(float &min, float &max, bool &logarithmic, Chris@133: QString &units) const Chris@133: { Chris@133: return false; Chris@133: } Chris@133: