00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "PluginParameterBox.h"
00017
00018 #include "AudioDial.h"
00019
00020 #include "plugin/PluginXml.h"
00021 #include "plugin/RealTimePluginInstance.h"
00022
00023 #include "base/RangeMapper.h"
00024
00025 #include <QDoubleSpinBox>
00026 #include <QGridLayout>
00027 #include <QComboBox>
00028 #include <QCheckBox>
00029 #include <QLayout>
00030 #include <QLabel>
00031
00032 #include <iostream>
00033 #include <string>
00034
00035 #include <cmath>
00036
00037 PluginParameterBox::PluginParameterBox(Vamp::PluginBase *plugin, QWidget *parent) :
00038 QFrame(parent),
00039 m_plugin(plugin),
00040 m_programCombo(0)
00041 {
00042 m_layout = new QGridLayout;
00043 setLayout(m_layout);
00044 populate();
00045 }
00046
00047 PluginParameterBox::~PluginParameterBox()
00048 {
00049 }
00050
00051 void
00052 PluginParameterBox::populate()
00053 {
00054 Vamp::PluginBase::ParameterList params = m_plugin->getParameterDescriptors();
00055 m_programs = m_plugin->getPrograms();
00056
00057 m_params.clear();
00058
00059 if (params.empty() && m_programs.empty()) {
00060 m_layout->addWidget
00061 (new QLabel(tr("This plugin has no adjustable parameters.")),
00062 0, 0);
00063 }
00064
00065 int offset = 0;
00066
00067 if (!m_programs.empty()) {
00068
00069 std::string currentProgram = m_plugin->getCurrentProgram();
00070
00071 m_programCombo = new QComboBox;
00072 m_programCombo->setMaxVisibleItems
00073 (m_programs.size() < 25 ? m_programs.size() : 20);
00074
00075 for (size_t i = 0; i < m_programs.size(); ++i) {
00076 m_programCombo->addItem(m_programs[i].c_str());
00077 if (m_programs[i] == currentProgram) {
00078 m_programCombo->setCurrentIndex(i);
00079 }
00080 }
00081
00082 m_layout->addWidget(new QLabel(tr("Program")), 0, 0);
00083 m_layout->addWidget(m_programCombo, 0, 1, 1, 2);
00084
00085 connect(m_programCombo, SIGNAL(currentIndexChanged(const QString &)),
00086 this, SLOT(programComboChanged(const QString &)));
00087
00088 offset = 1;
00089 }
00090
00091 for (size_t i = 0; i < params.size(); ++i) {
00092
00093 QString identifier = params[i].identifier.c_str();
00094 QString name = params[i].name.c_str();
00095 QString unit = params[i].unit.c_str();
00096
00097 float min = params[i].minValue;
00098 float max = params[i].maxValue;
00099 float deft = params[i].defaultValue;
00100 float value = m_plugin->getParameter(params[i].identifier);
00101
00102 int hint = PortHint::NoHint;
00103 RealTimePluginInstance *rtpi = dynamic_cast<RealTimePluginInstance *>
00104 (m_plugin);
00105 if (rtpi) {
00106 hint = rtpi->getParameterDisplayHint(i);
00107 }
00108
00109 float qtz = 0.0;
00110 if (params[i].isQuantized) qtz = params[i].quantizeStep;
00111
00112 std::cerr << "PluginParameterBox: hint = " << hint << ", min = " << min << ", max = "
00113 << max << ", qtz = " << qtz << std::endl;
00114
00115 std::vector<std::string> valueNames = params[i].valueNames;
00116
00117
00118
00119 int imin = 0, imax = 100;
00120
00121 if (!(hint & PortHint::Logarithmic)) {
00122 if (qtz > 0.0) {
00123 imax = int((max - min) / qtz);
00124 } else {
00125 qtz = (max - min) / 100.0;
00126 }
00127 }
00128
00130
00131
00132 QLabel *label = new QLabel(name);
00133 if (params[i].description != "") {
00134 label->setToolTip(params[i].description.c_str());
00135 }
00136 m_layout->addWidget(label, i + offset, 0);
00137
00138 ParamRec rec;
00139 rec.param = params[i];
00140 rec.dial = 0;
00141 rec.spin = 0;
00142 rec.check = 0;
00143 rec.combo = 0;
00144
00145 if (params[i].isQuantized && !valueNames.empty()) {
00146
00147 QComboBox *combobox = new QComboBox;
00148 combobox->setObjectName(identifier);
00149 for (unsigned int j = 0; j < valueNames.size(); ++j) {
00150 combobox->addItem(valueNames[j].c_str());
00151 if ((unsigned int)(lrintf(fabsf((value - min) / qtz))) == j) {
00152 combobox->setCurrentIndex(j);
00153 }
00154 }
00155 connect(combobox, SIGNAL(activated(int)),
00156 this, SLOT(dialChanged(int)));
00157 m_layout->addWidget(combobox, i + offset, 1, 1, 2);
00158 rec.combo = combobox;
00159
00160 } else if (min == 0.0 && max == 1.0 && qtz == 1.0) {
00161
00162 QCheckBox *checkbox = new QCheckBox;
00163 checkbox->setObjectName(identifier);
00164 checkbox->setCheckState(value < 0.5 ? Qt::Unchecked : Qt::Checked);
00165 connect(checkbox, SIGNAL(stateChanged(int)),
00166 this, SLOT(checkBoxChanged(int)));
00167 m_layout->addWidget(checkbox, i + offset, 2);
00168 rec.check = checkbox;
00169
00170 } else {
00171
00172 AudioDial *dial = new AudioDial;
00173 dial->setObjectName(name);
00174 dial->setMinimum(imin);
00175 dial->setMaximum(imax);
00176 dial->setPageStep(1);
00177 dial->setNotchesVisible((imax - imin) <= 12);
00179
00180 dial->setFixedWidth(32);
00181 dial->setFixedHeight(32);
00182 RangeMapper *rm = 0;
00183 if (hint & PortHint::Logarithmic) {
00184 rm = new LogRangeMapper(imin, imax, min, max, unit);
00185 } else {
00186 rm = new LinearRangeMapper(imin, imax, min, max, unit);
00187 }
00188 dial->setRangeMapper(rm);
00189 dial->setDefaultValue(rm->getPositionForValue(deft));
00190 dial->setValue(rm->getPositionForValue(value));
00191 dial->setShowToolTip(true);
00192 connect(dial, SIGNAL(valueChanged(int)),
00193 this, SLOT(dialChanged(int)));
00194 m_layout->addWidget(dial, i + offset, 1);
00195
00196 QDoubleSpinBox *spinbox = new QDoubleSpinBox;
00197 spinbox->setObjectName(identifier);
00198 spinbox->setMinimum(min);
00199 spinbox->setMaximum(max);
00200 spinbox->setSuffix(QString(" %1").arg(unit));
00201 if (qtz != 0) spinbox->setSingleStep(qtz);
00202 spinbox->setValue(value);
00203 spinbox->setDecimals(4);
00204 connect(spinbox, SIGNAL(valueChanged(double)),
00205 this, SLOT(spinBoxChanged(double)));
00206 m_layout->addWidget(spinbox, i + offset, 2);
00207 rec.dial = dial;
00208 rec.spin = spinbox;
00209 }
00210
00211 m_params[identifier] = rec;
00212 m_nameMap[name] = identifier;
00213 }
00214 }
00215
00216 void
00217 PluginParameterBox::dialChanged(int ival)
00218 {
00219 QObject *obj = sender();
00220 QString identifier = obj->objectName();
00221
00222 if (m_params.find(identifier) == m_params.end() &&
00223 m_nameMap.find(identifier) != m_nameMap.end()) {
00224 identifier = m_nameMap[identifier];
00225 }
00226
00227 if (m_params.find(identifier) == m_params.end()) {
00228 std::cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << identifier.toStdString() << "\"" << std::endl;
00229 return;
00230 }
00231
00232 Vamp::PluginBase::ParameterDescriptor params = m_params[identifier].param;
00233
00234 float min = params.minValue;
00235 float max = params.maxValue;
00236
00237 float newValue;
00238
00239 float qtz = 0.0;
00240 if (params.isQuantized) qtz = params.quantizeStep;
00241
00242 AudioDial *ad = dynamic_cast<AudioDial *>(obj);
00243
00244 if (ad && ad->rangeMapper()) {
00245
00246 newValue = ad->mappedValue();
00247 if (newValue < min) newValue = min;
00248 if (newValue > max) newValue = max;
00249 if (qtz != 0.0) {
00250 ival = lrintf((newValue - min) / qtz);
00251 newValue = min + ival * qtz;
00252 }
00253
00254 } else {
00255 if (qtz == 0.0) {
00256 qtz = (max - min) / 100.0;
00257 }
00258 newValue = min + ival * qtz;
00259 }
00260
00261 std::cerr << "PluginParameterBox::dialChanged: newValue = " << newValue << std::endl;
00262
00263 QDoubleSpinBox *spin = m_params[identifier].spin;
00264 if (spin) {
00265 spin->blockSignals(true);
00266 spin->setValue(newValue);
00267 spin->blockSignals(false);
00268 }
00269
00270 m_plugin->setParameter(identifier.toStdString(), newValue);
00271
00272 updateProgramCombo();
00273
00274 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
00275 }
00276
00277 void
00278 PluginParameterBox::checkBoxChanged(int state)
00279 {
00280 QObject *obj = sender();
00281 QString identifier = obj->objectName();
00282
00283 if (m_params.find(identifier) == m_params.end() &&
00284 m_nameMap.find(identifier) != m_nameMap.end()) {
00285 identifier = m_nameMap[identifier];
00286 }
00287
00288 if (m_params.find(identifier) == m_params.end()) {
00289 std::cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << identifier.toStdString() << "\"" << std::endl;
00290 return;
00291 }
00292
00293 Vamp::PluginBase::ParameterDescriptor params = m_params[identifier].param;
00294
00295 if (state) m_plugin->setParameter(identifier.toStdString(), 1.0);
00296 else m_plugin->setParameter(identifier.toStdString(), 0.0);
00297
00298 updateProgramCombo();
00299
00300 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
00301 }
00302
00303 void
00304 PluginParameterBox::spinBoxChanged(double value)
00305 {
00306 QObject *obj = sender();
00307 QString identifier = obj->objectName();
00308
00309 if (m_params.find(identifier) == m_params.end() &&
00310 m_nameMap.find(identifier) != m_nameMap.end()) {
00311 identifier = m_nameMap[identifier];
00312 }
00313
00314 if (m_params.find(identifier) == m_params.end()) {
00315 std::cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << identifier.toStdString() << "\"" << std::endl;
00316 return;
00317 }
00318
00319 Vamp::PluginBase::ParameterDescriptor params = m_params[identifier].param;
00320
00321 float min = params.minValue;
00322 float max = params.maxValue;
00323
00324 float qtz = 0.0;
00325 if (params.isQuantized) qtz = params.quantizeStep;
00326
00327 if (qtz > 0.0) {
00328 int step = int((value - min) / qtz);
00329 value = min + step * qtz;
00330 }
00331
00332 int imax = 100;
00333
00334 if (qtz > 0.0) {
00335 imax = int((max - min) / qtz);
00336 } else {
00337 qtz = (max - min) / 100.0;
00338 }
00339
00340 int ival = lrintf((value - min) / qtz);
00341
00342 AudioDial *dial = m_params[identifier].dial;
00343 if (dial) {
00344 dial->blockSignals(true);
00345 if (dial->rangeMapper()) {
00346 dial->setMappedValue(value);
00347 } else {
00348 dial->setValue(ival);
00349 }
00350 dial->blockSignals(false);
00351 }
00352
00353 m_plugin->setParameter(identifier.toStdString(), value);
00354
00355 updateProgramCombo();
00356
00357 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
00358 }
00359
00360 void
00361 PluginParameterBox::programComboChanged(const QString &newProgram)
00362 {
00363 m_plugin->selectProgram(newProgram.toStdString());
00364
00365 for (std::map<QString, ParamRec>::iterator i = m_params.begin();
00366 i != m_params.end(); ++i) {
00367
00368 Vamp::PluginBase::ParameterDescriptor ¶m = i->second.param;
00369 float value = m_plugin->getParameter(param.identifier);
00370
00371 if (i->second.spin) {
00372 i->second.spin->blockSignals(true);
00373 i->second.spin->setValue(value);
00374 i->second.spin->blockSignals(false);
00375 }
00376
00377 if (i->second.dial) {
00378
00379 float min = param.minValue;
00380 float max = param.maxValue;
00381
00382 float qtz = 0.0;
00383 if (param.isQuantized) qtz = param.quantizeStep;
00384
00385 if (qtz == 0.0) {
00386 qtz = (max - min) / 100.0;
00387 }
00388
00389 i->second.dial->blockSignals(true);
00390 i->second.dial->setValue(lrintf((value - min) / qtz));
00391 i->second.dial->blockSignals(false);
00392 }
00393
00394 if (i->second.combo) {
00395 i->second.combo->blockSignals(true);
00396 i->second.combo->setCurrentIndex(lrintf(value));
00397 i->second.combo->blockSignals(false);
00398 }
00399
00400 if (i->second.check) {
00401 i->second.check->blockSignals(true);
00402 i->second.check->setCheckState(value < 0.5 ? Qt::Unchecked : Qt::Checked);
00403 i->second.check->blockSignals(false);
00404 }
00405 }
00406
00407 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
00408 }
00409
00410 void
00411 PluginParameterBox::updateProgramCombo()
00412 {
00413 if (!m_programCombo || m_programs.empty()) return;
00414
00415 std::string currentProgram = m_plugin->getCurrentProgram();
00416
00417 for (size_t i = 0; i < m_programs.size(); ++i) {
00418 if (m_programs[i] == currentProgram) {
00419 m_programCombo->setCurrentIndex(i);
00420 }
00421 }
00422 }
00423
00424