annotate widgets/PluginParameterBox.cpp @ 65:7f608ec9a061

* More structural work on feature extraction plugin C <-> C++ adapter * Allow use of LADSPA/DSSI plugins with control outputs as feature extraction plugins (DSSI with MIDI output still to come) * Reorder labels on spectrogram status box * Minor tweaks in doc etc.
author Chris Cannam
date Mon, 27 Mar 2006 15:03:02 +0000
parents 10bcd53ddc71
children 72fa239a4880
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@60 20 #include <QDoubleSpinBox>
Chris@60 21 #include <QGridLayout>
Chris@63 22 #include <QComboBox>
Chris@63 23 #include <QCheckBox>
Chris@60 24 #include <QLayout>
Chris@60 25 #include <QLabel>
Chris@60 26
Chris@60 27 #include <iostream>
Chris@60 28 #include <string>
Chris@60 29
Chris@62 30 PluginParameterBox::PluginParameterBox(PluginInstance *plugin, QWidget *parent) :
Chris@62 31 QFrame(parent),
Chris@60 32 m_plugin(plugin)
Chris@60 33 {
Chris@60 34 m_layout = new QGridLayout;
Chris@60 35 setLayout(m_layout);
Chris@60 36 populate();
Chris@60 37 }
Chris@60 38
Chris@60 39 PluginParameterBox::~PluginParameterBox()
Chris@60 40 {
Chris@60 41 }
Chris@60 42
Chris@60 43 void
Chris@60 44 PluginParameterBox::populate()
Chris@60 45 {
Chris@60 46 PluginInstance::ParameterList params = m_plugin->getParameterDescriptors();
Chris@63 47 PluginInstance::ProgramList programs = m_plugin->getPrograms();
Chris@60 48
Chris@60 49 m_params.clear();
Chris@60 50
Chris@63 51 if (params.empty() && programs.empty()) {
Chris@62 52 m_layout->addWidget
Chris@62 53 (new QLabel(tr("This plugin has no adjustable parameters.")),
Chris@62 54 0, 0);
Chris@62 55 }
Chris@62 56
Chris@63 57 int offset = 0;
Chris@63 58
Chris@63 59 if (!programs.empty()) {
Chris@63 60
Chris@63 61 std::string currentProgram = m_plugin->getCurrentProgram();
Chris@63 62
Chris@63 63 QComboBox *programCombo = new QComboBox;
Chris@63 64 programCombo->setMaxVisibleItems(20);
Chris@63 65
Chris@63 66 for (int i = 0; i < programs.size(); ++i) {
Chris@63 67 programCombo->addItem(programs[i].c_str());
Chris@63 68 if (programs[i] == currentProgram) {
Chris@63 69 programCombo->setCurrentIndex(i);
Chris@63 70 }
Chris@63 71 }
Chris@63 72
Chris@63 73 m_layout->addWidget(new QLabel(tr("Program")), 0, 0);
Chris@63 74 m_layout->addWidget(programCombo, 0, 1, 1, 2);
Chris@63 75
Chris@63 76 connect(programCombo, SIGNAL(currentIndexChanged(const QString &)),
Chris@63 77 this, SLOT(programComboChanged(const QString &)));
Chris@63 78
Chris@63 79 offset = 1;
Chris@63 80 }
Chris@63 81
Chris@60 82 for (size_t i = 0; i < params.size(); ++i) {
Chris@60 83
Chris@60 84 QString name = params[i].name.c_str();
Chris@60 85 QString description = params[i].description.c_str();
Chris@60 86 QString unit = params[i].unit.c_str();
Chris@60 87
Chris@60 88 float min = params[i].minValue;
Chris@60 89 float max = params[i].maxValue;
Chris@60 90 float deft = params[i].defaultValue;
Chris@62 91 float value = m_plugin->getParameter(params[i].name);
Chris@60 92
Chris@60 93 float qtz = 0.0;
Chris@60 94 if (params[i].isQuantized) qtz = params[i].quantizeStep;
Chris@60 95
Chris@60 96 // construct an integer range
Chris@60 97
Chris@60 98 int imin = 0, imax = 100;
Chris@60 99
Chris@60 100 if (qtz > 0.0) {
Chris@60 101 imax = int((max - min) / qtz);
Chris@60 102 } else {
Chris@60 103 qtz = (max - min) / 100.0;
Chris@60 104 }
Chris@60 105
Chris@60 106 //!!! would be nice to ensure the default value corresponds to
Chris@60 107 // an integer!
Chris@60 108
Chris@60 109 QLabel *label = new QLabel(description);
Chris@63 110 m_layout->addWidget(label, i + offset, 0);
Chris@60 111
Chris@60 112 ParamRec rec;
Chris@60 113 rec.param = params[i];
Chris@63 114 rec.dial = 0;
Chris@63 115 rec.spin = 0;
Chris@63 116 rec.check = 0;
Chris@63 117
Chris@63 118 if (min == 0.0 && max == 1.0 && qtz == 1.0) {
Chris@63 119
Chris@63 120 QCheckBox *checkbox = new QCheckBox;
Chris@63 121 checkbox->setObjectName(name);
Chris@63 122 checkbox->setCheckState(value == 0.0 ? Qt::Unchecked : Qt::Checked);
Chris@63 123 connect(checkbox, SIGNAL(stateChanged(int)),
Chris@63 124 this, SLOT(checkBoxChanged(int)));
Chris@63 125 m_layout->addWidget(checkbox, i + offset, 2);
Chris@63 126 rec.check = checkbox;
Chris@63 127
Chris@63 128 } else {
Chris@63 129
Chris@63 130 AudioDial *dial = new AudioDial;
Chris@63 131 dial->setObjectName(name);
Chris@63 132 dial->setMinimum(imin);
Chris@63 133 dial->setMaximum(imax);
Chris@63 134 dial->setPageStep(1);
Chris@63 135 dial->setNotchesVisible((imax - imin) <= 12);
Chris@63 136 dial->setDefaultValue(int((deft - min) / qtz));
Chris@63 137 dial->setValue(int((value - min) / qtz));
Chris@63 138 dial->setFixedWidth(32);
Chris@63 139 dial->setFixedHeight(32);
Chris@63 140 connect(dial, SIGNAL(valueChanged(int)),
Chris@63 141 this, SLOT(dialChanged(int)));
Chris@63 142 m_layout->addWidget(dial, i + offset, 1);
Chris@63 143
Chris@63 144 QDoubleSpinBox *spinbox = new QDoubleSpinBox;
Chris@63 145 spinbox->setObjectName(name);
Chris@63 146 spinbox->setMinimum(min);
Chris@63 147 spinbox->setMaximum(max);
Chris@63 148 spinbox->setSuffix(QString(" %1").arg(unit));
Chris@63 149 spinbox->setSingleStep(qtz);
Chris@63 150 spinbox->setValue(value);
Chris@63 151 connect(spinbox, SIGNAL(valueChanged(double)),
Chris@63 152 this, SLOT(spinBoxChanged(double)));
Chris@63 153 m_layout->addWidget(spinbox, i + offset, 2);
Chris@63 154 rec.dial = dial;
Chris@63 155 rec.spin = spinbox;
Chris@63 156 }
Chris@63 157
Chris@60 158 m_params[name] = rec;
Chris@60 159 }
Chris@60 160 }
Chris@60 161
Chris@60 162 void
Chris@60 163 PluginParameterBox::dialChanged(int ival)
Chris@60 164 {
Chris@60 165 QObject *obj = sender();
Chris@60 166 QString name = obj->objectName();
Chris@60 167
Chris@60 168 if (m_params.find(name) == m_params.end()) {
Chris@60 169 std::cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@60 170 return;
Chris@60 171 }
Chris@60 172
Chris@60 173 PluginInstance::ParameterDescriptor params = m_params[name].param;
Chris@60 174
Chris@60 175 float min = params.minValue;
Chris@60 176 float max = params.maxValue;
Chris@60 177
Chris@60 178 float qtz = 0.0;
Chris@60 179 if (params.isQuantized) qtz = params.quantizeStep;
Chris@60 180
Chris@60 181 if (qtz == 0.0) {
Chris@60 182 qtz = (max - min) / 100.0;
Chris@60 183 }
Chris@60 184
Chris@60 185 float newValue = min + ival * qtz;
Chris@60 186
Chris@60 187 QDoubleSpinBox *spin = m_params[name].spin;
Chris@63 188 if (spin) {
Chris@63 189 spin->blockSignals(true);
Chris@63 190 spin->setValue(newValue);
Chris@63 191 spin->blockSignals(false);
Chris@63 192 }
Chris@60 193
Chris@60 194 m_plugin->setParameter(name.toStdString(), newValue);
Chris@64 195
Chris@64 196 emit pluginConfigurationChanged(m_plugin->toXmlString());
Chris@60 197 }
Chris@60 198
Chris@60 199 void
Chris@63 200 PluginParameterBox::checkBoxChanged(int state)
Chris@63 201 {
Chris@63 202 QObject *obj = sender();
Chris@63 203 QString name = obj->objectName();
Chris@63 204
Chris@63 205 if (m_params.find(name) == m_params.end()) {
Chris@63 206 std::cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@63 207 return;
Chris@63 208 }
Chris@63 209
Chris@63 210 PluginInstance::ParameterDescriptor params = m_params[name].param;
Chris@63 211
Chris@63 212 if (state) m_plugin->setParameter(name.toStdString(), 1.0);
Chris@63 213 else m_plugin->setParameter(name.toStdString(), 0.0);
Chris@64 214
Chris@64 215 emit pluginConfigurationChanged(m_plugin->toXmlString());
Chris@63 216 }
Chris@63 217
Chris@63 218 void
Chris@60 219 PluginParameterBox::spinBoxChanged(double value)
Chris@60 220 {
Chris@60 221 QObject *obj = sender();
Chris@60 222 QString name = obj->objectName();
Chris@60 223
Chris@60 224 if (m_params.find(name) == m_params.end()) {
Chris@60 225 std::cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@60 226 return;
Chris@60 227 }
Chris@60 228
Chris@60 229 PluginInstance::ParameterDescriptor params = m_params[name].param;
Chris@60 230
Chris@60 231 float min = params.minValue;
Chris@60 232 float max = params.maxValue;
Chris@60 233
Chris@60 234 float qtz = 0.0;
Chris@60 235 if (params.isQuantized) qtz = params.quantizeStep;
Chris@60 236
Chris@60 237 if (qtz > 0.0) {
Chris@60 238 int step = int((value - min) / qtz);
Chris@60 239 value = min + step * qtz;
Chris@60 240 }
Chris@60 241
Chris@60 242 int imin = 0, imax = 100;
Chris@60 243
Chris@60 244 if (qtz > 0.0) {
Chris@60 245 imax = int((max - min) / qtz);
Chris@60 246 } else {
Chris@60 247 qtz = (max - min) / 100.0;
Chris@60 248 }
Chris@60 249
Chris@60 250 int ival = (value - min) / qtz;
Chris@60 251
Chris@60 252 AudioDial *dial = m_params[name].dial;
Chris@63 253 if (dial) {
Chris@63 254 dial->blockSignals(true);
Chris@63 255 dial->setValue(ival);
Chris@63 256 dial->blockSignals(false);
Chris@63 257 }
Chris@60 258
Chris@60 259 m_plugin->setParameter(name.toStdString(), value);
Chris@64 260
Chris@64 261 emit pluginConfigurationChanged(m_plugin->toXmlString());
Chris@60 262 }
Chris@60 263
Chris@63 264 void
Chris@63 265 PluginParameterBox::programComboChanged(const QString &newProgram)
Chris@63 266 {
Chris@63 267 m_plugin->selectProgram(newProgram.toStdString());
Chris@60 268
Chris@63 269 for (std::map<QString, ParamRec>::iterator i = m_params.begin();
Chris@63 270 i != m_params.end(); ++i) {
Chris@63 271
Chris@63 272 PluginInstance::ParameterDescriptor &param = i->second.param;
Chris@63 273 float value = m_plugin->getParameter(param.name);
Chris@63 274
Chris@63 275 if (i->second.spin) {
Chris@63 276 i->second.spin->blockSignals(true);
Chris@63 277 i->second.spin->setValue(value);
Chris@63 278 i->second.spin->blockSignals(false);
Chris@63 279 }
Chris@63 280
Chris@63 281 if (i->second.dial) {
Chris@63 282
Chris@63 283 float min = param.minValue;
Chris@63 284 float max = param.maxValue;
Chris@63 285
Chris@63 286 float qtz = 0.0;
Chris@63 287 if (param.isQuantized) qtz = param.quantizeStep;
Chris@63 288
Chris@63 289 if (qtz == 0.0) {
Chris@63 290 qtz = (max - min) / 100.0;
Chris@63 291 }
Chris@63 292
Chris@63 293 i->second.dial->blockSignals(true);
Chris@63 294 i->second.dial->setValue(int((value - min) / qtz));
Chris@63 295 i->second.dial->blockSignals(false);
Chris@63 296 }
Chris@63 297 }
Chris@64 298
Chris@64 299 emit pluginConfigurationChanged(m_plugin->toXmlString());
Chris@63 300 }
Chris@63 301