# HG changeset patch # User Chris Cannam # Date 1157988769 0 # Node ID 5ec6b60658d8c8916341142849a1e2855d34c0d5 # Parent 0f1ac9562c76e76b0c0e11041cc43f79fa1c8c97 * Pull window type selector and shape preview out into their own widgets (from the preferences dialog) diff -r 0f1ac9562c76 -r 5ec6b60658d8 widgets/WindowShapePreview.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/WindowShapePreview.cpp Mon Sep 11 15:32:49 2006 +0000 @@ -0,0 +1,207 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + 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. See the file + COPYING included with this distribution for more information. +*/ + +#include "WindowShapePreview.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +WindowShapePreview::WindowShapePreview(QWidget *parent) : + QFrame(parent), + m_windowType(WindowType(999)) +{ + QHBoxLayout *layout = new QHBoxLayout; + layout->setMargin(0); + setLayout(layout); + m_windowTimeExampleLabel = new QLabel; + m_windowFreqExampleLabel = new QLabel; + layout->addWidget(m_windowTimeExampleLabel); + layout->addWidget(m_windowFreqExampleLabel); +} + +WindowShapePreview::~WindowShapePreview() +{ +} + +void +WindowShapePreview::updateLabels() +{ + int step = 24; + int peak = 48; + int w = step * 4, h = 64; + WindowType type = m_windowType; + Window windower = Window(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(); + + int 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 = " <setPixmap(freqLabel); +} + +void +WindowShapePreview::setWindowType(WindowType type) +{ + if (m_windowType == type) return; + m_windowType = type; + updateLabels(); +} + diff -r 0f1ac9562c76 -r 5ec6b60658d8 widgets/WindowShapePreview.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/WindowShapePreview.h Mon Sep 11 15:32:49 2006 +0000 @@ -0,0 +1,44 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + 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. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef _WINDOW_SHAPE_PREVIEW_H_ +#define _WINDOW_SHAPE_PREVIEW_H_ + +#include + +#include "base/Window.h" + +class QLabel; + +class WindowShapePreview : public QFrame +{ + Q_OBJECT + +public: + WindowShapePreview(QWidget *parent = 0); + virtual ~WindowShapePreview(); + +public slots: + void setWindowType(WindowType type); + +protected: + QLabel *m_windowTimeExampleLabel; + QLabel *m_windowFreqExampleLabel; + WindowType m_windowType; + + void updateLabels(); +}; + +#endif diff -r 0f1ac9562c76 -r 5ec6b60658d8 widgets/WindowTypeSelector.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/WindowTypeSelector.cpp Mon Sep 11 15:32:49 2006 +0000 @@ -0,0 +1,107 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + 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. See the file + COPYING included with this distribution for more information. +*/ + +#include "WindowTypeSelector.h" + +#include "WindowShapePreview.h" + +#include +#include + +#include "base/Preferences.h" + +WindowTypeSelector::WindowTypeSelector(WindowType defaultType, QWidget *parent) : + QFrame(parent), + m_windowType(WindowType(999)) +{ + QVBoxLayout *layout = new QVBoxLayout; + layout->setMargin(0); + setLayout(layout); + + // 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; + + Preferences *prefs = Preferences::getInstance(); + + m_windowShape = new WindowShapePreview; + + m_windowCombo = new QComboBox; + int min = 0, max = 0, i = 0; + int window = int(defaultType); + if (window == 999) { + window = prefs->getPropertyRangeAndValue("Window Type", &min, &max); + } + int index = 0; + + for (i = 0; i <= 8; ++i) { + m_windowCombo->addItem(prefs->getPropertyValueLabel("Window Type", + m_windows[i])); + if (m_windows[i] == window) index = i; + } + + m_windowCombo->setCurrentIndex(index); + + layout->addWidget(m_windowShape); + layout->addWidget(m_windowCombo); + + connect(m_windowCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(windowIndexChanged(int))); + windowIndexChanged(index); +} + +WindowTypeSelector::~WindowTypeSelector() +{ + delete[] m_windows; +} + +WindowType +WindowTypeSelector::getWindowType() const +{ + return m_windowType; +} + +void +WindowTypeSelector::setWindowType(WindowType type) +{ + if (type == m_windowType) return; + int index; + for (index = 0; index <= 8; ++index) { + if (m_windows[index] == type) break; + } + if (index <= 8) m_windowCombo->setCurrentIndex(index); + m_windowType = type; + m_windowShape->setWindowType(m_windowType); +} + +void +WindowTypeSelector::windowIndexChanged(int index) +{ + WindowType type = m_windows[index]; + if (type == m_windowType) return; + m_windowType = type; + m_windowShape->setWindowType(m_windowType); + emit windowTypeChanged(type); +} + diff -r 0f1ac9562c76 -r 5ec6b60658d8 widgets/WindowTypeSelector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/WindowTypeSelector.h Mon Sep 11 15:32:49 2006 +0000 @@ -0,0 +1,53 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + 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. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef _WINDOW_TYPE_SELECTOR_H_ +#define _WINDOW_TYPE_SELECTOR_H_ + +#include + +#include "base/Window.h" + +class WindowShapePreview; +class QComboBox; + +class WindowTypeSelector : public QFrame +{ + Q_OBJECT + +public: + WindowTypeSelector(WindowType defaultType = WindowType(999), // 999 -> get from preferences + QWidget *parent = 0); + virtual ~WindowTypeSelector(); + + WindowType getWindowType() const; + +signals: + void windowTypeChanged(WindowType type); + +public slots: + void setWindowType(WindowType type); + +protected slots: + void windowIndexChanged(int index); + +protected: + QComboBox *m_windowCombo; + WindowShapePreview *m_windowShape; + WindowType *m_windows; + WindowType m_windowType; +}; + +#endif diff -r 0f1ac9562c76 -r 5ec6b60658d8 widgets/widgets.pro --- a/widgets/widgets.pro Tue Sep 05 16:34:54 2006 +0000 +++ b/widgets/widgets.pro Mon Sep 11 15:32:49 2006 +0000 @@ -24,7 +24,9 @@ PluginParameterDialog.h \ PropertyBox.h \ PropertyStack.h \ - Thumbwheel.h + Thumbwheel.h \ + WindowShapePreview.h \ + WindowTypeSelector.h SOURCES += AudioDial.cpp \ Fader.cpp \ ItemEditDialog.cpp \ @@ -35,4 +37,6 @@ PluginParameterDialog.cpp \ PropertyBox.cpp \ PropertyStack.cpp \ - Thumbwheel.cpp + Thumbwheel.cpp \ + WindowShapePreview.cpp \ + WindowTypeSelector.cpp