[354ca9]: libgui / FrequencyResponseWidget.cpp Maximize Restore History

Download this file

FrequencyResponseWidget.cpp    128 lines (103 with data), 4.4 kB

  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
121
122
123
124
125
126
127
/***************************************************************************
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 "config.h"
#include <stdlib.h>
#include <math.h>
#include <qpainter.h>
#include "libkwave/TransmissionFunction.h"
#include "FrequencyResponseWidget.h"
//***************************************************************************
FrequencyResponseWidget::FrequencyResponseWidget(QWidget *widget,
const char *name)
:QWidget(widget, name), m_f_max(0), m_db_min(0), m_db_max(0),
m_decades(0), m_function(0), m_pixmap(0)
{
// this avoids flicker :-)
setBackgroundMode(NoBackground);
init(10000, -12, +12);
}
//***************************************************************************
FrequencyResponseWidget::~FrequencyResponseWidget()
{
if (m_pixmap) delete m_pixmap;
m_pixmap = 0;
}
//***************************************************************************
void FrequencyResponseWidget::init(double freq, int db_min, int db_max)
{
const int base = 10;
m_decades = (int)ceil(log(freq)/log(base));
m_f_max = pow(base, m_decades);
m_db_min = db_min;
m_db_max = db_max;
}
//***************************************************************************
void FrequencyResponseWidget::setFilter(TransmissionFunction *func)
{
m_function = func;
repaint();
}
//***************************************************************************
void 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;
if (!m_pixmap) m_pixmap = new QPixmap(width, height);
Q_ASSERT(m_pixmap);
if (!m_pixmap) return;
if ((m_pixmap->width() != width) || (m_pixmap->height() != height))
m_pixmap->resize(width, height);
QPainter p;
p.begin(m_pixmap);
m_pixmap->fill(colorGroup().dark());
double scale = (double)(height-1) / (double)(m_db_max-m_db_min);
double min = pow(10.0, (double)m_db_min/10.0);
double max = pow(10.0, (double)m_db_max/10.0);
p.setPen(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 * (double)x / (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 - (int)((db - m_db_min) * scale);
p.drawLine(x, y+1, x, height-1);
}
// draw the zero db line
p.setPen(colorGroup().text());
int y = height - (int)((0.0 - m_db_min) * scale);
p.drawLine(0, y, width-1, y);
p.end();
bitBlt(this, 0, 0, m_pixmap);
}
//***************************************************************************
#include "FrequencyResponseWidget.moc"
//***************************************************************************
//***************************************************************************