1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/***************************************************************************
FrequencyResponseWidget.cpp - displays a frequency response
-------------------
begin : Mar 09 2003
copyright : (C) 2003 by Thomas Eschenbacher
email : Thomas Eschenbacher <thomas.eschenbacher@gmx.de>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <math.h>
#include <stdlib.h>
#include <QBrush>
#include <QPainter>
#include <QPixmap>
#include "libkwave/TransmissionFunction.h"
#include "libkwave/Utils.h"
#include "libgui/FrequencyResponseWidget.h"
//***************************************************************************
Kwave::FrequencyResponseWidget::FrequencyResponseWidget(QWidget *widget)
:QWidget(widget), m_f_max(0), m_db_min(0), m_db_max(0),
m_decades(0), m_function(nullptr)
{
init(10000, -12, +12);
}
//***************************************************************************
Kwave::FrequencyResponseWidget::~FrequencyResponseWidget()
{
}
//***************************************************************************
void Kwave::FrequencyResponseWidget::init(double freq, int db_min, int db_max)
{
const int base = 10;
m_decades = Kwave::toInt(ceil(log(freq)/log(base)));
m_f_max = pow(base, m_decades);
m_db_min = db_min;
m_db_max = db_max;
}
//***************************************************************************
void Kwave::FrequencyResponseWidget::setFilter(
Kwave::TransmissionFunction *func)
{
m_function = func;
repaint();
}
//***************************************************************************
void Kwave::FrequencyResponseWidget::paintEvent(QPaintEvent*)
{
// const int base = 10;
// const double m_frequency = m_f_max * 2/3;
const int width = this->width();
const int height = this->height();
Q_ASSERT(width > 0);
Q_ASSERT(height > 0);
if ((width <= 0) || (height <= 0)) return;
QPainter p(this);
p.fillRect(rect(), QBrush(palette().dark()));
double scale = static_cast<double>(height-1) /
static_cast<double>(m_db_max-m_db_min);
double min = pow(10.0, static_cast<double>(m_db_min) / 10.0);
double max = pow(10.0, static_cast<double>(m_db_max) / 10.0);
p.setPen(Qt::green);//colorGroup().text());
for (int x=0; x < width; x++) {
// transform x coordinate to frequency
// // logarithmic frequency scale, didn't look so good :-(
// double f = pow(base, (double)m_decades * (double)x / (double)width);
// linear frequency scale
double f = (m_f_max * static_cast<double>(x) /
static_cast<double>(width));
// calculate the filter function's output at the given frequency
f = (f / m_f_max) * M_PI;
double a = (m_function) ? m_function->at(f): 1.0;
// limit to upper and lower margins
if (a < min) a = min;
if (a > max) a = max;
// convert to logarithmic scale
double db = 10.0 * log10(a);
// draw one line
int y = height - Kwave::toInt((db - m_db_min) * scale);
p.drawLine(x, y+1, x, height-1);
}
// draw the zero db line
p.setPen(palette().text().color());
int y = height - Kwave::toInt((0.0 - m_db_min) * scale);
p.drawLine(0, y, width-1, y);
}
//***************************************************************************
//***************************************************************************
#include "moc_FrequencyResponseWidget.cpp"
|