annotate widgets/PluginParameterBox.cpp @ 77:fd348f36c0d3

* Implement harmonic cursor in spectrogram * Implement layer export. This doesn't quite do the right thing for the SV XML layer export yet -- it doesn't include layer display information, so when imported, it only creates an invisible model. Could also do with fixing CSV file import so as to work correctly for note and text layers.
author Chris Cannam
date Mon, 10 Apr 2006 17:22:59 +0000
parents 195ad6178ef8
children 967193b6c7aa
rev   line source
Chris@60 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@60 2
Chris@60 3 /*
Chris@60 4 Sonic Visualiser
Chris@60 5 An audio file viewer and annotation editor.
Chris@60 6 Centre for Digital Music, Queen Mary, University of London.
Chris@60 7 This file copyright 2006 Chris Cannam.
Chris@60 8
Chris@60 9 This program is free software; you can redistribute it and/or
Chris@60 10 modify it under the terms of the GNU General Public License as
Chris@60 11 published by the Free Software Foundation; either version 2 of the
Chris@60 12 License, or (at your option) any later version. See the file
Chris@60 13 COPYING included with this distribution for more information.
Chris@60 14 */
Chris@60 15
Chris@60 16 #include "PluginParameterBox.h"
Chris@60 17
Chris@60 18 #include "AudioDial.h"
Chris@60 19
Chris@71 20 #include "plugin/PluginXml.h"
Chris@71 21
Chris@60 22 #include <QDoubleSpinBox>
Chris@60 23 #include <QGridLayout>
Chris@63 24 #include <QComboBox>
Chris@63 25 #include <QCheckBox>
Chris@60 26 #include <QLayout>
Chris@60 27 #include <QLabel>
Chris@60 28
Chris@60 29 #include <iostream>
Chris@60 30 #include <string>
Chris@60 31
Chris@71 32 PluginParameterBox::PluginParameterBox(Vamp::PluginBase *plugin, QWidget *parent) :
Chris@62 33 QFrame(parent),
Chris@60 34 m_plugin(plugin)
Chris@60 35 {
Chris@60 36 m_layout = new QGridLayout;
Chris@60 37 setLayout(m_layout);
Chris@60 38 populate();
Chris@60 39 }
Chris@60 40
Chris@60 41 PluginParameterBox::~PluginParameterBox()
Chris@60 42 {
Chris@60 43 }
Chris@60 44
Chris@60 45 void
Chris@60 46 PluginParameterBox::populate()
Chris@60 47 {
Chris@71 48 Vamp::PluginBase::ParameterList params = m_plugin->getParameterDescriptors();
Chris@71 49 Vamp::PluginBase::ProgramList programs = m_plugin->getPrograms();
Chris@60 50
Chris@60 51 m_params.clear();
Chris@60 52
Chris@63 53 if (params.empty() && programs.empty()) {
Chris@62 54 m_layout->addWidget
Chris@62 55 (new QLabel(tr("This plugin has no adjustable parameters.")),
Chris@62 56 0, 0);
Chris@62 57 }
Chris@62 58
Chris@63 59 int offset = 0;
Chris@63 60
Chris@63 61 if (!programs.empty()) {
Chris@63 62
Chris@63 63 std::string currentProgram = m_plugin->getCurrentProgram();
Chris@63 64
Chris@63 65 QComboBox *programCombo = new QComboBox;
Chris@63 66 programCombo->setMaxVisibleItems(20);
Chris@63 67
Chris@63 68 for (int i = 0; i < programs.size(); ++i) {
Chris@63 69 programCombo->addItem(programs[i].c_str());
Chris@63 70 if (programs[i] == currentProgram) {
Chris@63 71 programCombo->setCurrentIndex(i);
Chris@63 72 }
Chris@63 73 }
Chris@63 74
Chris@63 75 m_layout->addWidget(new QLabel(tr("Program")), 0, 0);
Chris@63 76 m_layout->addWidget(programCombo, 0, 1, 1, 2);
Chris@63 77
Chris@63 78 connect(programCombo, SIGNAL(currentIndexChanged(const QString &)),
Chris@63 79 this, SLOT(programComboChanged(const QString &)));
Chris@63 80
Chris@63 81 offset = 1;
Chris@63 82 }
Chris@63 83
Chris@60 84 for (size_t i = 0; i < params.size(); ++i) {
Chris@60 85
Chris@60 86 QString name = params[i].name.c_str();
Chris@60 87 QString description = params[i].description.c_str();
Chris@60 88 QString unit = params[i].unit.c_str();
Chris@60 89
Chris@60 90 float min = params[i].minValue;
Chris@60 91 float max = params[i].maxValue;
Chris@60 92 float deft = params[i].defaultValue;
Chris@62 93 float value = m_plugin->getParameter(params[i].name);
Chris@60 94
Chris@60 95 float qtz = 0.0;
Chris@60 96 if (params[i].isQuantized) qtz = params[i].quantizeStep;
Chris@60 97
Chris@74 98 std::vector<std::string> valueNames = params[i].valueNames;
Chris@74 99
Chris@60 100 // construct an integer range
Chris@60 101
Chris@60 102 int imin = 0, imax = 100;
Chris@60 103
Chris@60 104 if (qtz > 0.0) {
Chris@60 105 imax = int((max - min) / qtz);
Chris@60 106 } else {
Chris@60 107 qtz = (max - min) / 100.0;
Chris@60 108 }
Chris@60 109
Chris@60 110 //!!! would be nice to ensure the default value corresponds to
Chris@60 111 // an integer!
Chris@60 112
Chris@60 113 QLabel *label = new QLabel(description);
Chris@63 114 m_layout->addWidget(label, i + offset, 0);
Chris@60 115
Chris@60 116 ParamRec rec;
Chris@60 117 rec.param = params[i];
Chris@63 118 rec.dial = 0;
Chris@63 119 rec.spin = 0;
Chris@63 120 rec.check = 0;
Chris@74 121 rec.combo = 0;
Chris@63 122
Chris@74 123 if (params[i].isQuantized && !valueNames.empty()) {
Chris@74 124
Chris@74 125 QComboBox *combobox = new QComboBox;
Chris@74 126 combobox->setObjectName(name);
Chris@74 127 for (unsigned int j = 0; j < valueNames.size(); ++j) {
Chris@74 128 combobox->addItem(valueNames[j].c_str());
Chris@74 129 if (lrintf((value - min) / qtz) == j) {
Chris@74 130 combobox->setCurrentIndex(j);
Chris@74 131 }
Chris@74 132 }
Chris@74 133 connect(combobox, SIGNAL(activated(int)),
Chris@74 134 this, SLOT(dialChanged(int)));
Chris@74 135 m_layout->addWidget(combobox, i + offset, 1, 1, 2);
Chris@74 136 rec.combo = combobox;
Chris@74 137
Chris@74 138 } else if (min == 0.0 && max == 1.0 && qtz == 1.0) {
Chris@63 139
Chris@63 140 QCheckBox *checkbox = new QCheckBox;
Chris@63 141 checkbox->setObjectName(name);
Chris@63 142 checkbox->setCheckState(value == 0.0 ? Qt::Unchecked : Qt::Checked);
Chris@63 143 connect(checkbox, SIGNAL(stateChanged(int)),
Chris@63 144 this, SLOT(checkBoxChanged(int)));
Chris@63 145 m_layout->addWidget(checkbox, i + offset, 2);
Chris@63 146 rec.check = checkbox;
Chris@63 147
Chris@63 148 } else {
Chris@63 149
Chris@63 150 AudioDial *dial = new AudioDial;
Chris@63 151 dial->setObjectName(name);
Chris@63 152 dial->setMinimum(imin);
Chris@63 153 dial->setMaximum(imax);
Chris@63 154 dial->setPageStep(1);
Chris@63 155 dial->setNotchesVisible((imax - imin) <= 12);
Chris@74 156 dial->setDefaultValue(lrintf((deft - min) / qtz));
Chris@74 157 dial->setValue(lrintf((value - min) / qtz));
Chris@63 158 dial->setFixedWidth(32);
Chris@63 159 dial->setFixedHeight(32);
Chris@63 160 connect(dial, SIGNAL(valueChanged(int)),
Chris@63 161 this, SLOT(dialChanged(int)));
Chris@63 162 m_layout->addWidget(dial, i + offset, 1);
Chris@63 163
Chris@63 164 QDoubleSpinBox *spinbox = new QDoubleSpinBox;
Chris@63 165 spinbox->setObjectName(name);
Chris@63 166 spinbox->setMinimum(min);
Chris@63 167 spinbox->setMaximum(max);
Chris@63 168 spinbox->setSuffix(QString(" %1").arg(unit));
Chris@63 169 spinbox->setSingleStep(qtz);
Chris@63 170 spinbox->setValue(value);
Chris@63 171 connect(spinbox, SIGNAL(valueChanged(double)),
Chris@63 172 this, SLOT(spinBoxChanged(double)));
Chris@63 173 m_layout->addWidget(spinbox, i + offset, 2);
Chris@63 174 rec.dial = dial;
Chris@63 175 rec.spin = spinbox;
Chris@63 176 }
Chris@63 177
Chris@60 178 m_params[name] = rec;
Chris@60 179 }
Chris@60 180 }
Chris@60 181
Chris@60 182 void
Chris@60 183 PluginParameterBox::dialChanged(int ival)
Chris@60 184 {
Chris@60 185 QObject *obj = sender();
Chris@60 186 QString name = obj->objectName();
Chris@60 187
Chris@60 188 if (m_params.find(name) == m_params.end()) {
Chris@60 189 std::cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@60 190 return;
Chris@60 191 }
Chris@60 192
Chris@71 193 Vamp::PluginBase::ParameterDescriptor params = m_params[name].param;
Chris@60 194
Chris@60 195 float min = params.minValue;
Chris@60 196 float max = params.maxValue;
Chris@60 197
Chris@60 198 float qtz = 0.0;
Chris@60 199 if (params.isQuantized) qtz = params.quantizeStep;
Chris@60 200
Chris@60 201 if (qtz == 0.0) {
Chris@60 202 qtz = (max - min) / 100.0;
Chris@60 203 }
Chris@60 204
Chris@60 205 float newValue = min + ival * qtz;
Chris@60 206
Chris@60 207 QDoubleSpinBox *spin = m_params[name].spin;
Chris@63 208 if (spin) {
Chris@63 209 spin->blockSignals(true);
Chris@63 210 spin->setValue(newValue);
Chris@63 211 spin->blockSignals(false);
Chris@63 212 }
Chris@60 213
Chris@60 214 m_plugin->setParameter(name.toStdString(), newValue);
Chris@64 215
Chris@71 216 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@60 217 }
Chris@60 218
Chris@60 219 void
Chris@63 220 PluginParameterBox::checkBoxChanged(int state)
Chris@63 221 {
Chris@63 222 QObject *obj = sender();
Chris@63 223 QString name = obj->objectName();
Chris@63 224
Chris@63 225 if (m_params.find(name) == m_params.end()) {
Chris@63 226 std::cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@63 227 return;
Chris@63 228 }
Chris@63 229
Chris@71 230 Vamp::PluginBase::ParameterDescriptor params = m_params[name].param;
Chris@63 231
Chris@63 232 if (state) m_plugin->setParameter(name.toStdString(), 1.0);
Chris@63 233 else m_plugin->setParameter(name.toStdString(), 0.0);
Chris@64 234
Chris@71 235 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@63 236 }
Chris@63 237
Chris@63 238 void
Chris@60 239 PluginParameterBox::spinBoxChanged(double value)
Chris@60 240 {
Chris@60 241 QObject *obj = sender();
Chris@60 242 QString name = obj->objectName();
Chris@60 243
Chris@60 244 if (m_params.find(name) == m_params.end()) {
Chris@60 245 std::cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@60 246 return;
Chris@60 247 }
Chris@60 248
Chris@71 249 Vamp::PluginBase::ParameterDescriptor params = m_params[name].param;
Chris@60 250
Chris@60 251 float min = params.minValue;
Chris@60 252 float max = params.maxValue;
Chris@60 253
Chris@60 254 float qtz = 0.0;
Chris@60 255 if (params.isQuantized) qtz = params.quantizeStep;
Chris@60 256
Chris@60 257 if (qtz > 0.0) {
Chris@60 258 int step = int((value - min) / qtz);
Chris@60 259 value = min + step * qtz;
Chris@60 260 }
Chris@60 261
Chris@60 262 int imin = 0, imax = 100;
Chris@60 263
Chris@60 264 if (qtz > 0.0) {
Chris@60 265 imax = int((max - min) / qtz);
Chris@60 266 } else {
Chris@60 267 qtz = (max - min) / 100.0;
Chris@60 268 }
Chris@60 269
Chris@60 270 int ival = (value - min) / qtz;
Chris@60 271
Chris@60 272 AudioDial *dial = m_params[name].dial;
Chris@63 273 if (dial) {
Chris@63 274 dial->blockSignals(true);
Chris@63 275 dial->setValue(ival);
Chris@63 276 dial->blockSignals(false);
Chris@63 277 }
Chris@60 278
Chris@60 279 m_plugin->setParameter(name.toStdString(), value);
Chris@64 280
Chris@71 281 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@60 282 }
Chris@60 283
Chris@63 284 void
Chris@63 285 PluginParameterBox::programComboChanged(const QString &newProgram)
Chris@63 286 {
Chris@63 287 m_plugin->selectProgram(newProgram.toStdString());
Chris@60 288
Chris@63 289 for (std::map<QString, ParamRec>::iterator i = m_params.begin();
Chris@63 290 i != m_params.end(); ++i) {
Chris@63 291
Chris@71 292 Vamp::PluginBase::ParameterDescriptor &param = i->second.param;
Chris@63 293 float value = m_plugin->getParameter(param.name);
Chris@63 294
Chris@63 295 if (i->second.spin) {
Chris@63 296 i->second.spin->blockSignals(true);
Chris@63 297 i->second.spin->setValue(value);
Chris@63 298 i->second.spin->blockSignals(false);
Chris@63 299 }
Chris@63 300
Chris@63 301 if (i->second.dial) {
Chris@63 302
Chris@63 303 float min = param.minValue;
Chris@63 304 float max = param.maxValue;
Chris@63 305
Chris@63 306 float qtz = 0.0;
Chris@63 307 if (param.isQuantized) qtz = param.quantizeStep;
Chris@63 308
Chris@63 309 if (qtz == 0.0) {
Chris@63 310 qtz = (max - min) / 100.0;
Chris@63 311 }
Chris@63 312
Chris@63 313 i->second.dial->blockSignals(true);
Chris@74 314 i->second.dial->setValue(lrintf((value - min) / qtz));
Chris@63 315 i->second.dial->blockSignals(false);
Chris@63 316 }
Chris@74 317
Chris@74 318 if (i->second.combo) {
Chris@74 319 i->second.combo->blockSignals(true);
Chris@74 320 i->second.combo->setCurrentIndex(value);
Chris@74 321 i->second.combo->blockSignals(false);
Chris@74 322 }
Chris@63 323 }
Chris@64 324
Chris@71 325 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@63 326 }
Chris@63 327