Mercurial > hg > sonic-visualiser
diff main/PreferencesDialog.cpp @ 9:8b34a6460545
* Pull window type selector and shape preview out into their own widgets
(from the preferences dialog)
author | Chris Cannam |
---|---|
date | Mon, 11 Sep 2006 15:32:49 +0000 |
parents | d4487202d0e8 |
children | e3b32dc5180b |
line wrap: on
line diff
--- a/main/PreferencesDialog.cpp Wed Aug 16 14:56:53 2006 +0000 +++ b/main/PreferencesDialog.cpp Mon Sep 11 15:32:49 2006 +0000 @@ -23,13 +23,11 @@ #include <QLabel> #include <QPushButton> #include <QHBoxLayout> -#include <QPainter> -#include <QPainterPath> -#include <QFont> #include <QString> #include <fftw3.h> +#include "widgets/WindowTypeSelector.h" #include "base/Preferences.h" PreferencesDialog::PreferencesDialog(QWidget *parent, Qt::WFlags flags) : @@ -53,39 +51,14 @@ // refer to it m_applyButton = new QPushButton(tr("Apply")); - // The WindowType enum is in rather a ragbag order -- reorder it here - // in a more sensible order - m_windows = new WindowType[9]; - m_windows[0] = HanningWindow; - m_windows[1] = HammingWindow; - m_windows[2] = BlackmanWindow; - m_windows[3] = BlackmanHarrisWindow; - m_windows[4] = NuttallWindow; - m_windows[5] = GaussianWindow; - m_windows[6] = ParzenWindow; - m_windows[7] = BartlettWindow; - m_windows[8] = RectangularWindow; + int min, max, i; - QComboBox *windowCombo = new QComboBox; - int min, max, i; - int window = prefs->getPropertyRangeAndValue("Window Type", &min, &max); - m_windowType = window; - int index = 0; - - for (i = 0; i <= 8; ++i) { - windowCombo->addItem(prefs->getPropertyValueLabel("Window Type", - m_windows[i])); - if (m_windows[i] == window) index = i; - } + m_windowType = WindowType(prefs->getPropertyRangeAndValue + ("Window Type", &min, &max)); + m_windowTypeSelector = new WindowTypeSelector(m_windowType); - windowCombo->setCurrentIndex(index); - - m_windowTimeExampleLabel = new QLabel; - m_windowFreqExampleLabel = new QLabel; - - connect(windowCombo, SIGNAL(currentIndexChanged(int)), - this, SLOT(windowTypeChanged(int))); - windowTypeChanged(index); + connect(m_windowTypeSelector, SIGNAL(windowTypeChanged(WindowType)), + this, SLOT(windowTypeChanged(WindowType))); QCheckBox *smoothing = new QCheckBox; m_smoothSpectrogram = prefs->getSmoothSpectrogram(); @@ -141,10 +114,9 @@ subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Window Type"))), row, 0); - subgrid->addWidget(windowCombo, row++, 1, 1, 2); - - subgrid->addWidget(m_windowTimeExampleLabel, row, 1); - subgrid->addWidget(m_windowFreqExampleLabel, row, 2); + subgrid->addWidget(m_windowTypeSelector, row++, 1, 2, 2); + subgrid->setRowStretch(row, 10); + row++; QHBoxLayout *hbox = new QHBoxLayout; grid->addLayout(hbox, 1, 0); @@ -165,163 +137,11 @@ PreferencesDialog::~PreferencesDialog() { std::cerr << "PreferencesDialog::~PreferencesDialog()" << std::endl; - - delete[] m_windows; } void -PreferencesDialog::windowTypeChanged(int value) +PreferencesDialog::windowTypeChanged(WindowType type) { - int step = 24; - int peak = 48; - int w = step * 4, h = 64; - WindowType type = m_windows[value]; - Window<float> windower = Window<float>(type, step * 2); - - QPixmap timeLabel(w, h + 1); - timeLabel.fill(Qt::white); - QPainter timePainter(&timeLabel); - - QPainterPath path; - - path.moveTo(0, h - peak + 1); - path.lineTo(w, h - peak + 1); - - timePainter.setPen(Qt::gray); - timePainter.setRenderHint(QPainter::Antialiasing, true); - timePainter.drawPath(path); - - path = QPainterPath(); - - float acc[w]; - for (int i = 0; i < w; ++i) acc[i] = 0.f; - for (int j = 0; j < 3; ++j) { - for (int i = 0; i < step * 2; ++i) { - acc[j * step + i] += windower.getValue(i); - } - } - for (int i = 0; i < w; ++i) { - int y = h - int(peak * acc[i] + 0.001) + 1; - if (i == 0) path.moveTo(i, y); - else path.lineTo(i, y); - } - - timePainter.drawPath(path); - timePainter.setRenderHint(QPainter::Antialiasing, false); - - path = QPainterPath(); - - timePainter.setPen(Qt::black); - - for (int i = 0; i < step * 2; ++i) { - int y = h - int(peak * windower.getValue(i) + 0.001) + 1; - if (i == 0) path.moveTo(i + step, float(y)); - else path.lineTo(i + step, float(y)); - } - - if (type == RectangularWindow) { - timePainter.drawPath(path); - path = QPainterPath(); - } - - timePainter.setRenderHint(QPainter::Antialiasing, true); - path.addRect(0, 0, w, h + 1); - timePainter.drawPath(path); - - QFont font; - font.setPixelSize(10); - font.setItalic(true); - timePainter.setFont(font); - QString label = tr("V / time"); - timePainter.drawText(w - timePainter.fontMetrics().width(label) - 4, - timePainter.fontMetrics().ascent() + 1, label); - - m_windowTimeExampleLabel->setPixmap(timeLabel); - - int fw = 100; - - QPixmap freqLabel(fw, h + 1); - freqLabel.fill(Qt::white); - QPainter freqPainter(&freqLabel); - path = QPainterPath(); - - size_t fftsize = 512; - - float *input = (float *)fftwf_malloc(fftsize * sizeof(float)); - fftwf_complex *output = - (fftwf_complex *)fftwf_malloc(fftsize * sizeof(fftwf_complex)); - fftwf_plan plan = fftwf_plan_dft_r2c_1d(fftsize, input, output, - FFTW_ESTIMATE); - for (int i = 0; i < fftsize; ++i) input[i] = 0.f; - for (int i = 0; i < step * 2; ++i) { - input[fftsize/2 - step + i] = windower.getValue(i); - } - - fftwf_execute(plan); - fftwf_destroy_plan(plan); - - float maxdb = 0.f; - float mindb = 0.f; - bool first = true; - for (int i = 0; i < fftsize/2; ++i) { - float power = output[i][0] * output[i][0] + output[i][1] * output[i][1]; - float db = mindb; - if (power > 0) { - db = 20 * log10(power); - if (first || db > maxdb) maxdb = db; - if (first || db < mindb) mindb = db; - first = false; - } - } - - if (mindb > -80.f) mindb = -80.f; - - // -- no, don't use the actual mindb -- it's easier to compare - // plots with a fixed min value - mindb = -170.f; - - float maxval = maxdb + -mindb; - - float ly = h - ((-80.f + -mindb) / maxval) * peak + 1; - - path.moveTo(0, h - peak + 1); - path.lineTo(fw, h - peak + 1); - - freqPainter.setPen(Qt::gray); - freqPainter.setRenderHint(QPainter::Antialiasing, true); - freqPainter.drawPath(path); - - path = QPainterPath(); - freqPainter.setPen(Qt::black); - -// std::cerr << "maxdb = " << maxdb << ", mindb = " << mindb << ", maxval = " <<maxval << std::endl; - - for (int i = 0; i < fftsize/2; ++i) { - float power = output[i][0] * output[i][0] + output[i][1] * output[i][1]; - float db = 20 * log10(power); - float val = db + -mindb; - if (val < 0) val = 0; - float norm = val / maxval; - float x = (fw / float(fftsize/2)) * i; - float y = h - norm * peak + 1; - if (i == 0) path.moveTo(x, y); - else path.lineTo(x, y); - } - - freqPainter.setRenderHint(QPainter::Antialiasing, true); - path.addRect(0, 0, fw, h + 1); - freqPainter.drawPath(path); - - fftwf_free(input); - fftwf_free(output); - - freqPainter.setFont(font); - label = tr("dB / freq"); - freqPainter.drawText(fw - freqPainter.fontMetrics().width(label) - 4, - freqPainter.fontMetrics().ascent() + 1, label); - - m_windowFreqExampleLabel->setPixmap(freqLabel); - m_windowType = type; m_applyButton->setEnabled(true); }