Mercurial > hg > svapp
comparison framework/TransformUserConfigurator.cpp @ 205:a3fbd52031a5
* Provide callback for use when configuring a plugin with GUI
author | Chris Cannam |
---|---|
date | Fri, 08 Oct 2010 11:20:10 +0100 |
parents | |
children | 15057cf59da5 |
comparison
equal
deleted
inserted
replaced
204:5ee9e6bc21eb | 205:a3fbd52031a5 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 | |
8 This program is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU General Public License as | |
10 published by the Free Software Foundation; either version 2 of the | |
11 License, or (at your option) any later version. See the file | |
12 COPYING included with this distribution for more information. | |
13 */ | |
14 | |
15 #include "TransformUserConfigurator.h" | |
16 | |
17 #include "transform/TransformFactory.h" | |
18 | |
19 #include "widgets/PluginParameterDialog.h" | |
20 | |
21 #include "plugin/FeatureExtractionPluginFactory.h" | |
22 #include "plugin/RealTimePluginFactory.h" | |
23 #include "plugin/RealTimePluginInstance.h" | |
24 | |
25 #include "data/model/DenseTimeValueModel.h" | |
26 | |
27 #include <vamp-hostsdk/Plugin.h> | |
28 | |
29 #include <QStringList> | |
30 | |
31 #include <typeinfo> | |
32 | |
33 bool | |
34 TransformUserConfigurator::getChannelRange(TransformId identifier, | |
35 Vamp::PluginBase *plugin, | |
36 int &minChannels, int &maxChannels) | |
37 { | |
38 if (plugin && plugin->getType() == "Feature Extraction Plugin") { | |
39 Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin); | |
40 std::cerr << "TransformUserConfigurator::getChannelRange: is a VP" << std::endl; | |
41 minChannels = vp->getMinChannelCount(); | |
42 maxChannels = vp->getMaxChannelCount(); | |
43 return true; | |
44 } else { | |
45 std::cerr << "TransformUserConfigurator::getChannelRange: is not a VP" << std::endl; | |
46 return TransformFactory::getInstance()-> | |
47 getTransformChannelRange(identifier, minChannels, maxChannels); | |
48 } | |
49 } | |
50 | |
51 bool | |
52 TransformUserConfigurator::configure(ModelTransformer::Input &input, | |
53 Transform &transform, | |
54 Vamp::PluginBase *plugin, | |
55 Model *inputModel, | |
56 AudioPlaySource *source, | |
57 size_t startFrame, | |
58 size_t duration, | |
59 const QMap<QString, Model *> &modelMap, | |
60 QStringList candidateModelNames, | |
61 QString defaultModelName) | |
62 { | |
63 bool ok = false; | |
64 QString id = transform.getPluginIdentifier(); | |
65 QString output = transform.getOutput(); | |
66 QString outputLabel = ""; | |
67 QString outputDescription = ""; | |
68 | |
69 bool frequency = false; | |
70 bool effect = false; | |
71 bool generator = false; | |
72 | |
73 if (!plugin) return false; | |
74 | |
75 if (FeatureExtractionPluginFactory::instanceFor(id)) { | |
76 | |
77 Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin); | |
78 | |
79 frequency = (vp->getInputDomain() == Vamp::Plugin::FrequencyDomain); | |
80 | |
81 std::vector<Vamp::Plugin::OutputDescriptor> od = | |
82 vp->getOutputDescriptors(); | |
83 | |
84 std::cerr << "configure: looking for output: " << output.toStdString() << std::endl; | |
85 | |
86 if (od.size() > 1) { | |
87 for (size_t i = 0; i < od.size(); ++i) { | |
88 if (od[i].identifier == output.toStdString()) { | |
89 outputLabel = od[i].name.c_str(); | |
90 outputDescription = od[i].description.c_str(); | |
91 break; | |
92 } | |
93 } | |
94 } | |
95 | |
96 } else if (RealTimePluginFactory::instanceFor(id)) { | |
97 | |
98 RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id); | |
99 const RealTimePluginDescriptor *desc = factory->getPluginDescriptor(id); | |
100 | |
101 if (desc->audioInputPortCount > 0 && | |
102 desc->audioOutputPortCount > 0 && | |
103 !desc->isSynth) { | |
104 effect = true; | |
105 } | |
106 | |
107 if (desc->audioInputPortCount == 0) { | |
108 generator = true; | |
109 } | |
110 | |
111 if (output != "A") { | |
112 int outputNo = output.toInt(); | |
113 if (outputNo >= 0 && outputNo < int(desc->controlOutputPortCount)) { | |
114 outputLabel = desc->controlOutputPortNames[outputNo].c_str(); | |
115 } | |
116 } | |
117 | |
118 RealTimePluginInstance *rtp = | |
119 static_cast<RealTimePluginInstance *>(plugin); | |
120 | |
121 if (effect && source) { | |
122 std::cerr << "Setting auditioning effect" << std::endl; | |
123 source->setAuditioningEffect(rtp); | |
124 } | |
125 } | |
126 | |
127 int sourceChannels = 1; | |
128 if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { | |
129 sourceChannels = dynamic_cast<DenseTimeValueModel *>(inputModel) | |
130 ->getChannelCount(); | |
131 } | |
132 | |
133 int minChannels = 1, maxChannels = sourceChannels; | |
134 getChannelRange(transform.getIdentifier(), plugin, | |
135 minChannels, maxChannels); | |
136 | |
137 int targetChannels = sourceChannels; | |
138 if (!effect) { | |
139 if (sourceChannels < minChannels) targetChannels = minChannels; | |
140 if (sourceChannels > maxChannels) targetChannels = maxChannels; | |
141 } | |
142 | |
143 int defaultChannel = -1; //!!! no longer saved! [was context.channel] | |
144 | |
145 PluginParameterDialog *dialog = new PluginParameterDialog(plugin); | |
146 | |
147 dialog->setMoreInfoUrl(TransformFactory::getInstance()-> | |
148 getTransformInfoUrl(transform.getIdentifier())); | |
149 | |
150 if (candidateModelNames.size() > 1 && !generator) { | |
151 dialog->setCandidateInputModels(candidateModelNames, | |
152 defaultModelName); | |
153 } | |
154 | |
155 if (startFrame != 0 || duration != 0) { | |
156 dialog->setShowSelectionOnlyOption(true); | |
157 } | |
158 | |
159 if (targetChannels > 0) { | |
160 dialog->setChannelArrangement(sourceChannels, targetChannels, | |
161 defaultChannel); | |
162 } | |
163 | |
164 dialog->setOutputLabel(outputLabel, outputDescription); | |
165 | |
166 dialog->setShowProcessingOptions(true, frequency); | |
167 | |
168 if (dialog->exec() == QDialog::Accepted) { | |
169 ok = true; | |
170 } | |
171 | |
172 QString selectedInput = dialog->getInputModel(); | |
173 if (selectedInput != "") { | |
174 if (modelMap.contains(selectedInput)) { | |
175 inputModel = modelMap.value(selectedInput); | |
176 std::cerr << "Found selected input \"" << selectedInput.toStdString() << "\" in model map, result is " << inputModel << std::endl; | |
177 } else { | |
178 std::cerr << "Failed to find selected input \"" << selectedInput.toStdString() << "\" in model map" << std::endl; | |
179 } | |
180 } else { | |
181 std::cerr << "Selected input empty: \"" << selectedInput.toStdString() << "\"" << std::endl; | |
182 } | |
183 | |
184 // Write parameters back to transform object | |
185 TransformFactory::getInstance()-> | |
186 setParametersFromPlugin(transform, plugin); | |
187 | |
188 input.setChannel(dialog->getChannel()); | |
189 | |
190 //!!! The dialog ought to be taking & returning transform | |
191 //objects and input objects and stuff rather than passing | |
192 //around all this misc stuff, but that's for tomorrow | |
193 //(whenever that may be) | |
194 | |
195 if (startFrame != 0 || duration != 0) { | |
196 if (dialog->getSelectionOnly()) { | |
197 transform.setStartTime(RealTime::frame2RealTime | |
198 (startFrame, inputModel->getSampleRate())); | |
199 transform.setDuration(RealTime::frame2RealTime | |
200 (duration, inputModel->getSampleRate())); | |
201 } | |
202 } | |
203 | |
204 size_t stepSize = 0, blockSize = 0; | |
205 WindowType windowType = HanningWindow; | |
206 | |
207 dialog->getProcessingParameters(stepSize, | |
208 blockSize, | |
209 windowType); | |
210 | |
211 transform.setStepSize(stepSize); | |
212 transform.setBlockSize(blockSize); | |
213 transform.setWindowType(windowType); | |
214 | |
215 delete dialog; | |
216 | |
217 if (effect && source) { | |
218 source->setAuditioningEffect(0); | |
219 } | |
220 | |
221 return ok; | |
222 } | |
223 |