annotate widgets/PluginParameterDialog.cpp @ 146:a1f7d265ac79

* More to do with passing around step/blocksize etc from plugin dialog to plugins. Still some puzzling unresolved details.
author Chris Cannam
date Tue, 19 Sep 2006 14:37:06 +0000
parents 4d132a06db9b
children e2ad3543c8a1
rev   line source
Chris@62 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@62 2
Chris@62 3 /*
Chris@62 4 Sonic Visualiser
Chris@62 5 An audio file viewer and annotation editor.
Chris@62 6 Centre for Digital Music, Queen Mary, University of London.
Chris@62 7 This file copyright 2006 Chris Cannam.
Chris@62 8
Chris@62 9 This program is free software; you can redistribute it and/or
Chris@62 10 modify it under the terms of the GNU General Public License as
Chris@62 11 published by the Free Software Foundation; either version 2 of the
Chris@62 12 License, or (at your option) any later version. See the file
Chris@62 13 COPYING included with this distribution for more information.
Chris@62 14 */
Chris@62 15
Chris@62 16 #include "PluginParameterDialog.h"
Chris@62 17
Chris@62 18 #include "PluginParameterBox.h"
Chris@140 19 #include "WindowTypeSelector.h"
Chris@62 20
Chris@106 21 #include "vamp-sdk/Plugin.h"
Chris@106 22
Chris@62 23 #include <QGridLayout>
Chris@62 24 #include <QLabel>
Chris@62 25 #include <QGroupBox>
Chris@62 26 #include <QHBoxLayout>
Chris@143 27 #include <QVBoxLayout>
Chris@62 28 #include <QPushButton>
Chris@69 29 #include <QMessageBox>
Chris@69 30 #include <QComboBox>
Chris@143 31 #include <QSettings>
Chris@62 32
Chris@71 33 PluginParameterDialog::PluginParameterDialog(Vamp::PluginBase *plugin,
Chris@69 34 int sourceChannels,
Chris@69 35 int targetChannels,
Chris@69 36 int defaultChannel,
Chris@106 37 QString output,
Chris@140 38 bool showWindowSize,
Chris@140 39 bool showFrequencyDomainOptions,
Chris@62 40 QWidget *parent) :
Chris@62 41 QDialog(parent),
Chris@62 42 m_plugin(plugin),
Chris@69 43 m_channel(defaultChannel),
Chris@145 44 m_stepSize(0),
Chris@145 45 m_blockSize(0),
Chris@145 46 m_windowType(HanningWindow),
Chris@62 47 m_parameterBox(0)
Chris@62 48 {
Chris@122 49 setWindowTitle(tr("Plugin Parameters"));
Chris@122 50
Chris@62 51 QGridLayout *grid = new QGridLayout;
Chris@62 52 setLayout(grid);
Chris@62 53
Chris@62 54 QGroupBox *pluginBox = new QGroupBox;
Chris@62 55 pluginBox->setTitle(tr("Plugin"));
Chris@62 56 grid->addWidget(pluginBox, 0, 0);
Chris@62 57
Chris@62 58 QGridLayout *subgrid = new QGridLayout;
Chris@62 59 pluginBox->setLayout(subgrid);
Chris@62 60
Chris@63 61 subgrid->setSpacing(0);
Chris@63 62 subgrid->setMargin(10);
Chris@63 63
Chris@62 64 QFont font(pluginBox->font());
Chris@62 65 font.setBold(true);
Chris@62 66
Chris@62 67 QLabel *nameLabel = new QLabel(plugin->getDescription().c_str());
Chris@146 68 nameLabel->setWordWrap(true);
Chris@62 69 nameLabel->setFont(font);
Chris@62 70
Chris@62 71 QLabel *makerLabel = new QLabel(plugin->getMaker().c_str());
Chris@146 72 makerLabel->setWordWrap(true);
Chris@62 73
Chris@106 74 QLabel *outputLabel = 0;
Chris@106 75
Chris@106 76 if (output != "") {
Chris@106 77
Chris@106 78 Vamp::Plugin *fePlugin = dynamic_cast<Vamp::Plugin *>(plugin);
Chris@106 79
Chris@106 80 if (fePlugin) {
Chris@106 81
Chris@106 82 std::vector<Vamp::Plugin::OutputDescriptor> od =
Chris@106 83 fePlugin->getOutputDescriptors();
Chris@106 84
Chris@106 85 if (od.size() > 1) {
Chris@106 86
Chris@106 87 for (size_t i = 0; i < od.size(); ++i) {
Chris@106 88 if (od[i].name == output.toStdString()) {
Chris@106 89 outputLabel = new QLabel(od[i].description.c_str());
Chris@146 90 outputLabel->setWordWrap(true);
Chris@106 91 break;
Chris@106 92 }
Chris@106 93 }
Chris@106 94 }
Chris@146 95 } else {
Chris@146 96 std::cerr << "Plugin " << plugin << " is not a feature extraction plugin" << std::endl;//!!!
Chris@106 97 }
Chris@106 98 }
Chris@106 99
Chris@62 100 QLabel *versionLabel = new QLabel(QString("%1")
Chris@62 101 .arg(plugin->getPluginVersion()));
Chris@146 102 versionLabel->setWordWrap(true);
Chris@62 103
Chris@62 104 QLabel *copyrightLabel = new QLabel(plugin->getCopyright().c_str());
Chris@146 105 copyrightLabel->setWordWrap(true);
Chris@62 106
Chris@63 107 QLabel *typeLabel = new QLabel(plugin->getType().c_str());
Chris@146 108 typeLabel->setWordWrap(true);
Chris@63 109 typeLabel->setFont(font);
Chris@63 110
Chris@62 111 subgrid->addWidget(new QLabel(tr("Name:")), 0, 0);
Chris@62 112 subgrid->addWidget(nameLabel, 0, 1);
Chris@62 113
Chris@63 114 subgrid->addWidget(new QLabel(tr("Type:")), 1, 0);
Chris@63 115 subgrid->addWidget(typeLabel, 1, 1);
Chris@62 116
Chris@106 117 int outputOffset = 0;
Chris@106 118 if (outputLabel) {
Chris@106 119 subgrid->addWidget(new QLabel(tr("Output:")), 2, 0);
Chris@106 120 subgrid->addWidget(outputLabel, 2, 1);
Chris@106 121 outputOffset = 1;
Chris@106 122 }
Chris@62 123
Chris@106 124 subgrid->addWidget(new QLabel(tr("Maker:")), 2 + outputOffset, 0);
Chris@106 125 subgrid->addWidget(makerLabel, 2 + outputOffset, 1);
Chris@63 126
Chris@106 127 subgrid->addWidget(new QLabel(tr("Copyright: ")), 3 + outputOffset, 0);
Chris@106 128 subgrid->addWidget(copyrightLabel, 3 + outputOffset, 1);
Chris@106 129
Chris@106 130 subgrid->addWidget(new QLabel(tr("Version:")), 4 + outputOffset, 0);
Chris@106 131 subgrid->addWidget(versionLabel, 4 + outputOffset, 1);
Chris@62 132
Chris@62 133 subgrid->setColumnStretch(1, 2);
Chris@62 134
Chris@62 135 QGroupBox *paramBox = new QGroupBox;
Chris@62 136 paramBox->setTitle(tr("Plugin Parameters"));
Chris@62 137 grid->addWidget(paramBox, 1, 0);
Chris@62 138 grid->setRowStretch(1, 10);
Chris@62 139
Chris@62 140 QHBoxLayout *paramLayout = new QHBoxLayout;
Chris@63 141 paramLayout->setMargin(0);
Chris@62 142 paramBox->setLayout(paramLayout);
Chris@62 143
Chris@62 144 m_parameterBox = new PluginParameterBox(m_plugin);
Chris@64 145 connect(m_parameterBox, SIGNAL(pluginConfigurationChanged(QString)),
Chris@64 146 this, SIGNAL(pluginConfigurationChanged(QString)));
Chris@62 147 paramLayout->addWidget(m_parameterBox);
Chris@62 148
Chris@143 149 m_advanced = new QFrame;
Chris@143 150 QVBoxLayout *advancedLayout = new QVBoxLayout;
Chris@143 151 advancedLayout->setMargin(0);
Chris@143 152 m_advanced->setLayout(advancedLayout);
Chris@143 153 grid->addWidget(m_advanced, 2, 0);
Chris@143 154
Chris@143 155 bool haveAdvanced = false;
Chris@143 156
Chris@69 157 if (sourceChannels != targetChannels) {
Chris@69 158
Chris@69 159 // At the moment we can only cope with the case where
Chris@69 160 // sourceChannels > targetChannels and targetChannels == 1
Chris@69 161
Chris@69 162 if (sourceChannels < targetChannels) {
Chris@69 163
Chris@69 164 QMessageBox::warning
Chris@69 165 (parent,
Chris@69 166 tr("Channel mismatch"),
Chris@69 167 tr("This plugin requires at least %1 input channels, but only %2 %3 available. The plugin probably will not work correctly.").arg(targetChannels).arg(sourceChannels).arg(sourceChannels != 1 ? tr("are") : tr("is")),
Chris@69 168 QMessageBox::Ok,
Chris@69 169 QMessageBox::NoButton);
Chris@69 170
Chris@69 171 } else {
Chris@69 172
Chris@69 173 QGroupBox *channelBox = new QGroupBox;
Chris@69 174 channelBox->setTitle(tr("Channels"));
Chris@143 175 advancedLayout->addWidget(channelBox);
Chris@143 176 haveAdvanced = true;
Chris@69 177
Chris@69 178 QVBoxLayout *channelLayout = new QVBoxLayout;
Chris@69 179 channelBox->setLayout(channelLayout);
Chris@69 180
Chris@69 181 if (targetChannels != 1) {
Chris@69 182
Chris@69 183 channelLayout->addWidget
Chris@69 184 (new QLabel(tr("This plugin accepts no more than %1 input channels,\nbut %2 are available. Only the first %3 will be used.\n")
Chris@69 185 .arg(targetChannels)
Chris@69 186 .arg(sourceChannels)
Chris@69 187 .arg(targetChannels)));
Chris@69 188
Chris@69 189 } else {
Chris@69 190
Chris@69 191 channelLayout->addWidget(new QLabel(tr("This plugin only has a single channel input,\nbut the source has %1 channels.").arg(sourceChannels)));
Chris@69 192
Chris@69 193 QComboBox *channelCombo = new QComboBox;
Chris@76 194 channelCombo->addItem(tr("Use mean of source channels"));
Chris@69 195 for (int i = 0; i < sourceChannels; ++i) {
Chris@69 196 channelCombo->addItem(tr("Use channel %1 only").arg(i + 1));
Chris@69 197 }
Chris@69 198
Chris@69 199 connect(channelCombo, SIGNAL(activated(int)),
Chris@69 200 this, SLOT(channelComboChanged(int)));
Chris@69 201
Chris@69 202 channelLayout->addWidget(channelCombo);
Chris@69 203 }
Chris@69 204 }
Chris@69 205 }
Chris@69 206
Chris@140 207 if (showWindowSize) {
Chris@140 208
Chris@140 209 Vamp::Plugin *fePlugin = dynamic_cast<Vamp::Plugin *>(plugin);
Chris@140 210 int size = 1024;
Chris@140 211 int increment = 1024;
Chris@140 212 if (fePlugin) {
Chris@140 213 size = fePlugin->getPreferredBlockSize();
Chris@146 214 std::cerr << "Feature extraction plugin \"" << fePlugin->getDescription() << "\" reports preferred block size as " << size << std::endl;
Chris@140 215 if (size == 0) size = 1024;
Chris@140 216 increment = fePlugin->getPreferredStepSize();
Chris@146 217 if (increment == 0) {
Chris@146 218 if (fePlugin->getInputDomain() == Vamp::Plugin::TimeDomain) {
Chris@146 219 increment = size;
Chris@146 220 } else {
Chris@146 221 increment = size/2;
Chris@146 222 }
Chris@146 223 }
Chris@146 224 } else {
Chris@146 225 std::cerr << "Plugin " << plugin << " is not a feature extraction plugin" << std::endl;//!!!
Chris@140 226 }
Chris@140 227
Chris@140 228 QGroupBox *windowBox = new QGroupBox;
Chris@140 229 windowBox->setTitle(tr("Processing"));
Chris@143 230 advancedLayout->addWidget(windowBox);
Chris@143 231 haveAdvanced = true;
Chris@140 232
Chris@140 233 QGridLayout *windowLayout = new QGridLayout;
Chris@140 234 windowBox->setLayout(windowLayout);
Chris@140 235
Chris@140 236 if (showFrequencyDomainOptions) {
Chris@140 237 windowLayout->addWidget(new QLabel(tr("Window size:")), 0, 0);
Chris@140 238 } else {
Chris@140 239 windowLayout->addWidget(new QLabel(tr("Audio frames per block:")), 0, 0);
Chris@140 240 }
Chris@140 241
Chris@143 242 std::cerr << "size: " << size << ", increment: " << increment << std::endl;
Chris@143 243
Chris@145 244 //!!! deal with block and step sizes (coming from the plugin's
Chris@145 245 // preferences) that don't fit into the default list
Chris@145 246
Chris@140 247 QComboBox *blockSizeCombo = new QComboBox;
Chris@140 248 blockSizeCombo->setEditable(true);
Chris@143 249 for (int i = 0; i < 14; ++i) {
Chris@140 250 int val = pow(2, i + 3);
Chris@140 251 blockSizeCombo->addItem(QString("%1").arg(val));
Chris@140 252 if (val == size) blockSizeCombo->setCurrentIndex(i);
Chris@140 253 }
Chris@143 254 blockSizeCombo->setValidator(new QIntValidator(1, pow(2, 18), this));
Chris@146 255 connect(blockSizeCombo, SIGNAL(textChanged(QString)),
Chris@145 256 this, SLOT(blockSizeComboChanged(QString)));
Chris@140 257 windowLayout->addWidget(blockSizeCombo, 0, 1);
Chris@140 258
Chris@140 259 if (showFrequencyDomainOptions) {
Chris@140 260
Chris@140 261 windowLayout->addWidget(new QLabel(tr("Window increment:")), 1, 0);
Chris@140 262
Chris@140 263 QComboBox *incrementCombo = new QComboBox;
Chris@140 264 incrementCombo->setEditable(true);
Chris@143 265 for (int i = 0; i < 14; ++i) {
Chris@140 266 int val = pow(2, i + 3);
Chris@140 267 incrementCombo->addItem(QString("%1").arg(val));
Chris@143 268 if (val == increment) incrementCombo->setCurrentIndex(i);
Chris@140 269 }
Chris@143 270 incrementCombo->setValidator(new QIntValidator(1, pow(2, 18), this));
Chris@146 271 connect(incrementCombo, SIGNAL(textChanged(QString)),
Chris@145 272 this, SLOT(incrementComboChanged(QString)));
Chris@140 273 windowLayout->addWidget(incrementCombo, 1, 1);
Chris@140 274
Chris@140 275 windowLayout->addWidget(new QLabel(tr("Window shape:")), 2, 0);
Chris@140 276 WindowTypeSelector *windowTypeSelector = new WindowTypeSelector;
Chris@145 277 connect(windowTypeSelector, SIGNAL(windowTypeChanged(WindowType type)),
Chris@145 278 this, SLOT(windowTypeChanged(type)));
Chris@140 279 windowLayout->addWidget(windowTypeSelector, 2, 1);
Chris@140 280 }
Chris@140 281 }
Chris@140 282
Chris@62 283 QHBoxLayout *hbox = new QHBoxLayout;
Chris@140 284 grid->addLayout(hbox, 4, 0);
Chris@143 285
Chris@143 286 bool advancedVisible = false;
Chris@143 287
Chris@143 288 if (haveAdvanced) {
Chris@143 289
Chris@143 290 m_advancedButton = new QPushButton(tr("Advanced >>"));
Chris@143 291 m_advancedButton->setCheckable(true);
Chris@143 292 connect(m_advancedButton, SIGNAL(clicked()), this, SLOT(advancedToggled()));
Chris@143 293
Chris@143 294 QSettings settings;
Chris@143 295 settings.beginGroup("PluginParameterDialog");
Chris@143 296 advancedVisible = settings.value("advancedvisible", false).toBool();
Chris@143 297 settings.endGroup();
Chris@143 298
Chris@143 299 m_advanced->setVisible(false);
Chris@143 300
Chris@143 301 hbox->addWidget(m_advancedButton);
Chris@143 302 }
Chris@143 303
Chris@62 304 QPushButton *ok = new QPushButton(tr("OK"));
Chris@62 305 QPushButton *cancel = new QPushButton(tr("Cancel"));
Chris@62 306 hbox->addStretch(10);
Chris@62 307 hbox->addWidget(ok);
Chris@62 308 hbox->addWidget(cancel);
Chris@62 309 connect(ok, SIGNAL(clicked()), this, SLOT(accept()));
Chris@62 310 connect(cancel, SIGNAL(clicked()), this, SLOT(reject()));
Chris@143 311
Chris@143 312 if (advancedVisible) {
Chris@143 313 m_advancedButton->setChecked(true);
Chris@143 314 advancedToggled();
Chris@143 315 }
Chris@62 316 }
Chris@62 317
Chris@62 318 PluginParameterDialog::~PluginParameterDialog()
Chris@62 319 {
Chris@62 320 }
Chris@62 321
Chris@69 322 void
Chris@145 323 PluginParameterDialog::getProcessingParameters(size_t &blockSize) const
Chris@145 324 {
Chris@145 325 blockSize = m_blockSize;
Chris@145 326 return;
Chris@145 327 }
Chris@145 328
Chris@145 329 void
Chris@145 330 PluginParameterDialog::getProcessingParameters(size_t &stepSize,
Chris@145 331 size_t &blockSize,
Chris@145 332 WindowType &windowType) const
Chris@145 333 {
Chris@145 334 stepSize = m_stepSize;
Chris@145 335 blockSize = m_blockSize;
Chris@145 336 windowType = m_windowType;
Chris@146 337 return;
Chris@145 338 }
Chris@145 339
Chris@145 340 void
Chris@145 341 PluginParameterDialog::blockSizeComboChanged(QString text)
Chris@145 342 {
Chris@145 343 m_blockSize = text.toInt();
Chris@146 344 std::cerr << "Block size changed to " << m_blockSize << std::endl;
Chris@145 345 }
Chris@145 346
Chris@145 347 void
Chris@145 348 PluginParameterDialog::incrementComboChanged(QString text)
Chris@145 349 {
Chris@145 350 m_stepSize = text.toInt();
Chris@146 351 //!!! rename increment to step size throughout
Chris@146 352 std::cerr << "Increment changed to " << m_blockSize << std::endl;
Chris@145 353 }
Chris@145 354
Chris@145 355 void
Chris@145 356 PluginParameterDialog::windowTypeChanged(WindowType type)
Chris@145 357 {
Chris@145 358 m_windowType = type;
Chris@145 359 }
Chris@145 360
Chris@145 361 void
Chris@143 362 PluginParameterDialog::advancedToggled()
Chris@143 363 {
Chris@143 364 bool visible = !m_advanced->isVisible();
Chris@143 365
Chris@143 366 m_advanced->setVisible(visible);
Chris@143 367
Chris@143 368 if (visible) m_advancedButton->setText(tr("Advanced <<"));
Chris@143 369 else m_advancedButton->setText(tr("Advanced >>"));
Chris@143 370
Chris@143 371 QSettings settings;
Chris@143 372 settings.beginGroup("PluginParameterDialog");
Chris@143 373 settings.setValue("advancedvisible", visible);
Chris@143 374 settings.endGroup();
Chris@143 375
Chris@143 376 std::cerr << "resize to " << sizeHint().width() << " x " << sizeHint().height() << std::endl;
Chris@143 377
Chris@143 378 setMaximumSize(sizeHint());
Chris@143 379 }
Chris@143 380
Chris@143 381 void
Chris@69 382 PluginParameterDialog::channelComboChanged(int index)
Chris@69 383 {
Chris@69 384 m_channel = index - 1;
Chris@69 385 }
Chris@69 386