18 #include <QHBoxLayout> 21 #include <QPainterPath> 25 #include <bqfft/FFT.h> 36 m_windowType(HanningWindow)
38 QHBoxLayout *layout =
new QHBoxLayout;
54 float scaleRatio = float(QFontMetrics(font()).height()) / 14.f;
55 if (scaleRatio < 1.f) scaleRatio = 1.f;
57 int step = int(24 * scaleRatio);
58 float peak = float(48 * scaleRatio);
60 int w = step * 4, h = int((peak * 4) / 3);
63 Window<float> windower = Window<float>(type, step * 2);
65 QPixmap timeLabel(w, h + 1);
66 timeLabel.fill(Qt::white);
67 QPainter timePainter(&timeLabel);
71 path.moveTo(0,
float(h) - peak + 1);
72 path.lineTo(w,
float(h) - peak + 1);
74 timePainter.setPen(Qt::gray);
75 timePainter.setRenderHint(QPainter::Antialiasing,
true);
76 timePainter.drawPath(path);
78 path = QPainterPath();
80 float *acc =
new float[w];
81 for (
int i = 0; i < w; ++i) acc[i] = 0.f;
82 for (
int j = 0; j < 3; ++j) {
83 for (
int i = 0; i < step * 2; ++i) {
84 acc[j * step + i] += windower.getValue(i);
87 for (
int i = 0; i < w; ++i) {
88 int y = h - int(peak * acc[i] + 0.001f) + 1;
89 if (i == 0) path.moveTo(i, y);
90 else path.lineTo(i, y);
94 timePainter.drawPath(path);
95 timePainter.setRenderHint(QPainter::Antialiasing,
false);
97 path = QPainterPath();
99 timePainter.setPen(Qt::black);
101 for (
int i = 0; i < step * 2; ++i) {
102 int y = h - int(peak * windower.getValue(i) + 0.001) + 1;
103 if (i == 0) path.moveTo(i + step,
float(y));
104 else path.lineTo(i + step,
float(y));
107 if (type == RectangularWindow) {
108 timePainter.drawPath(path);
109 path = QPainterPath();
112 timePainter.setRenderHint(QPainter::Antialiasing,
true);
113 path.addRect(0, 0, w, h + 1);
114 timePainter.drawPath(path);
119 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 122 font.setPixelSize(
int(10 * scaleRatio));
123 font.setItalic(
true);
124 timePainter.setFont(font);
125 QString label = tr(
"V / time");
126 timePainter.drawText(w - timePainter.fontMetrics().width(label) - 4,
127 timePainter.fontMetrics().ascent() + 1, label);
131 QPixmap freqLabel(w, h + 1);
132 freqLabel.fill(Qt::white);
133 QPainter freqPainter(&freqLabel);
134 path = QPainterPath();
138 breakfastquay::FFT fft(fftsize);
140 vector<float> input(fftsize);
141 vector<complex<float>> output(fftsize/2 + 1);
143 for (
int i = 0; i < fftsize; ++i) input[i] = 0.f;
144 for (
int i = 0; i < step * 2; ++i) {
145 input[fftsize/2 - step + i] = windower.getValue(i);
148 fft.forwardInterleaved(input.data(),
reinterpret_cast<float *
>(output.data()));
153 for (
int i = 0; i < fftsize/2; ++i) {
155 output[i].real() * output[i].real() +
156 output[i].imag() * output[i].imag();
159 db = 20.f * log10f(power);
160 if (first || db > maxdb) maxdb = db;
161 if (first || db < mindb) mindb = db;
166 if (mindb > -80.f) mindb = -80.f;
172 float maxval = maxdb + -mindb;
176 path.moveTo(0,
float(h) - peak + 1);
177 path.lineTo(w,
float(h) - peak + 1);
179 freqPainter.setPen(Qt::gray);
180 freqPainter.setRenderHint(QPainter::Antialiasing,
true);
181 freqPainter.drawPath(path);
183 path = QPainterPath();
184 freqPainter.setPen(Qt::black);
188 for (
int i = 0; i < fftsize/2; ++i) {
190 output[i].real() * output[i].real() +
191 output[i].imag() * output[i].imag();
192 float db = 20.f * log10f(power);
193 float val = db + -mindb;
194 if (val < 0) val = 0;
195 float norm = val / maxval;
196 float x = (float(w) / float(fftsize/2)) *
float(i);
197 float y = float(h) - norm * peak + 1;
198 if (i == 0) path.moveTo(x, y);
199 else path.lineTo(x, y);
202 freqPainter.setRenderHint(QPainter::Antialiasing,
true);
203 path.addRect(0, 0, w, h + 1);
204 freqPainter.drawPath(path);
206 freqPainter.setFont(font);
207 label = tr(
"dB / freq");
208 freqPainter.drawText(w - freqPainter.fontMetrics().width(label) - 4,
209 freqPainter.fontMetrics().ascent() + 1, label);
WindowShapePreview(QWidget *parent=0)
QLabel * m_windowTimeExampleLabel
virtual ~WindowShapePreview()
void setWindowType(WindowType type)
QLabel * m_windowFreqExampleLabel