svapp
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 00008 This program is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU General Public License as 00010 published by the Free Software Foundation; either version 2 of the 00011 License, or (at your option) any later version. See the file 00012 COPYING included with this distribution for more information. 00013 */ 00014 00015 #include "TransformUserConfigurator.h" 00016 00017 #include "transform/TransformFactory.h" 00018 00019 #include "widgets/PluginParameterDialog.h" 00020 00021 #include "plugin/FeatureExtractionPluginFactory.h" 00022 #include "plugin/RealTimePluginFactory.h" 00023 #include "plugin/RealTimePluginInstance.h" 00024 00025 #include "data/model/DenseTimeValueModel.h" 00026 00027 #include <vamp-hostsdk/Plugin.h> 00028 00029 #include <QStringList> 00030 00031 #include <typeinfo> 00032 00033 static QWidget *parentWidget = 0; 00034 00035 void 00036 TransformUserConfigurator::setParentWidget(QWidget *w) 00037 { 00038 parentWidget = w; 00039 } 00040 00041 bool 00042 TransformUserConfigurator::getChannelRange(TransformId identifier, 00043 Vamp::PluginBase *plugin, 00044 int &minChannels, int &maxChannels) 00045 { 00046 if (plugin && plugin->getType() == "Feature Extraction Plugin") { 00047 Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin); 00048 SVDEBUG << "TransformUserConfigurator::getChannelRange: is a VP" << endl; 00049 minChannels = vp->getMinChannelCount(); 00050 maxChannels = vp->getMaxChannelCount(); 00051 return true; 00052 } else { 00053 SVDEBUG << "TransformUserConfigurator::getChannelRange: is not a VP" << endl; 00054 return TransformFactory::getInstance()-> 00055 getTransformChannelRange(identifier, minChannels, maxChannels); 00056 } 00057 } 00058 00059 bool 00060 TransformUserConfigurator::configure(ModelTransformer::Input &input, 00061 Transform &transform, 00062 Vamp::PluginBase *plugin, 00063 Model *&inputModel, 00064 AudioPlaySource *source, 00065 int startFrame, 00066 int duration, 00067 const QMap<QString, Model *> &modelMap, 00068 QStringList candidateModelNames, 00069 QString defaultModelName) 00070 { 00071 bool ok = false; 00072 QString id = transform.getPluginIdentifier(); 00073 QString output = transform.getOutput(); 00074 QString outputLabel = ""; 00075 QString outputDescription = ""; 00076 00077 bool frequency = false; 00078 bool effect = false; 00079 bool generator = false; 00080 00081 if (!plugin) return false; 00082 00083 if (FeatureExtractionPluginFactory::instanceFor(id)) { 00084 00085 Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin); 00086 00087 frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain); 00088 00089 std::vector<Vamp::Plugin::OutputDescriptor> od = 00090 vp->getOutputDescriptors(); 00091 00092 cerr << "configure: looking for output: " << output << endl; 00093 00094 if (od.size() > 1) { 00095 for (size_t i = 0; i < od.size(); ++i) { 00096 if (od[i].identifier == output.toStdString()) { 00097 outputLabel = od[i].name.c_str(); 00098 outputDescription = od[i].description.c_str(); 00099 break; 00100 } 00101 } 00102 } 00103 00104 } else if (RealTimePluginFactory::instanceFor(id)) { 00105 00106 RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id); 00107 const RealTimePluginDescriptor *desc = factory->getPluginDescriptor(id); 00108 00109 if (desc->audioInputPortCount > 0 && 00110 desc->audioOutputPortCount > 0 && 00111 !desc->isSynth) { 00112 effect = true; 00113 } 00114 00115 if (desc->audioInputPortCount == 0) { 00116 generator = true; 00117 } 00118 00119 if (output != "A") { 00120 int outputNo = output.toInt(); 00121 if (outputNo >= 0 && outputNo < int(desc->controlOutputPortCount)) { 00122 outputLabel = desc->controlOutputPortNames[outputNo].c_str(); 00123 } 00124 } 00125 00126 RealTimePluginInstance *rtp = 00127 static_cast<RealTimePluginInstance *>(plugin); 00128 00129 if (effect && source) { 00130 SVDEBUG << "Setting auditioning effect" << endl; 00131 source->setAuditioningEffect(rtp); 00132 } 00133 } 00134 00135 int sourceChannels = 1; 00136 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { 00137 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel) 00138 ->getChannelCount(); 00139 } 00140 00141 int minChannels = 1, maxChannels = sourceChannels; 00142 getChannelRange(transform.getIdentifier(), plugin, 00143 minChannels, maxChannels); 00144 00145 int targetChannels = sourceChannels; 00146 if (!effect) { 00147 if (sourceChannels < minChannels) targetChannels = minChannels; 00148 if (sourceChannels > maxChannels) targetChannels = maxChannels; 00149 } 00150 00151 int defaultChannel = -1; 00152 00153 PluginParameterDialog *dialog = new PluginParameterDialog 00154 (plugin, parentWidget); 00155 00156 dialog->setMoreInfoUrl(TransformFactory::getInstance()-> 00157 getTransformInfoUrl(transform.getIdentifier())); 00158 00159 if (candidateModelNames.size() > 1 && !generator) { 00160 dialog->setCandidateInputModels(candidateModelNames, 00161 defaultModelName); 00162 } 00163 00164 if (startFrame != 0 || duration != 0) { 00165 dialog->setShowSelectionOnlyOption(true); 00166 } 00167 00168 if (targetChannels > 0) { 00169 dialog->setChannelArrangement(sourceChannels, targetChannels, 00170 defaultChannel); 00171 } 00172 00173 dialog->setOutputLabel(outputLabel, outputDescription); 00174 00175 dialog->setShowProcessingOptions(true, frequency); 00176 00177 if (dialog->exec() == QDialog::Accepted) { 00178 ok = true; 00179 } 00180 00181 QString selectedInput = dialog->getInputModel(); 00182 if (selectedInput != "") { 00183 if (modelMap.contains(selectedInput)) { 00184 inputModel = modelMap.value(selectedInput); 00185 cerr << "Found selected input \"" << selectedInput << "\" in model map, result is " << inputModel << endl; 00186 } else { 00187 cerr << "Failed to find selected input \"" << selectedInput << "\" in model map" << endl; 00188 } 00189 } else { 00190 cerr << "Selected input empty: \"" << selectedInput << "\"" << endl; 00191 } 00192 00193 // Write parameters back to transform object 00194 TransformFactory::getInstance()-> 00195 setParametersFromPlugin(transform, plugin); 00196 00197 input.setChannel(dialog->getChannel()); 00198 00200 //objects and input objects and stuff rather than passing 00201 //around all this misc stuff, but that's for tomorrow 00202 //(whenever that may be) 00203 00204 if (startFrame != 0 || duration != 0) { 00205 if (dialog->getSelectionOnly()) { 00206 transform.setStartTime(RealTime::frame2RealTime 00207 (startFrame, inputModel->getSampleRate())); 00208 transform.setDuration(RealTime::frame2RealTime 00209 (duration, inputModel->getSampleRate())); 00210 } 00211 } 00212 00213 int stepSize = 0, blockSize = 0; 00214 WindowType windowType = HanningWindow; 00215 00216 dialog->getProcessingParameters(stepSize, 00217 blockSize, 00218 windowType); 00219 00220 transform.setStepSize(stepSize); 00221 transform.setBlockSize(blockSize); 00222 transform.setWindowType(windowType); 00223 00224 delete dialog; 00225 00226 if (effect && source) { 00227 source->setAuditioningEffect(0); 00228 } 00229 00230 return ok; 00231 } 00232