comparison VamPipePluginLibrary.cpp @ 98:22a09aca4b4a

Remove use of excessively bulky RequestOrResponse type, also reducing amount of code the library implementation
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 19 Sep 2016 16:35:05 +0100
parents 95643de89a08
children e18e15bedd72
comparison
equal deleted inserted replaced
97:95643de89a08 98:22a09aca4b4a
71 string key = p->getStaticData().pluginKey; 71 string key = p->getStaticData().pluginKey;
72 m_adapters[key] = p; 72 m_adapters[key] = p;
73 } 73 }
74 } 74 }
75 75
76 RequestOrResponse
77 VamPipePluginLibrary::readRequest(string req)
78 {
79 RequestOrResponse rr;
80 rr.direction = RequestOrResponse::Request;
81
82 Json j = convertRequestJson(req);
83
84 //!!! reduce, reduce
85 rr.type = VampJson::getRequestResponseType(j);
86 VampJson::BufferSerialisation serialisation = VampJson::BufferSerialisation::Text;
87
88 switch (rr.type) {
89
90 case RRType::List:
91 VampJson::toVampRequest_List(j); // type check only
92 break;
93 case RRType::Load:
94 rr.loadRequest = VampJson::toVampRequest_Load(j);
95 break;
96 case RRType::Configure:
97 rr.configurationRequest = VampJson::toVampRequest_Configure(j, m_mapper);
98 break;
99 case RRType::Process:
100 rr.processRequest = VampJson::toVampRequest_Process(j, m_mapper, serialisation);
101 break;
102 case RRType::Finish:
103 rr.finishRequest = VampJson::toVampRequest_Finish(j, m_mapper);
104 break;
105 case RRType::NotValid:
106 break;
107 }
108
109 if (serialisation == VampJson::BufferSerialisation::Base64) {
110 m_useBase64 = true;
111 }
112
113 return rr;
114 }
115
116 string
117 VamPipePluginLibrary::writeResponse(const RequestOrResponse &rr) const
118 {
119 Json j;
120
121 VampJson::BufferSerialisation serialisation =
122 (m_useBase64 ?
123 VampJson::BufferSerialisation::Base64 :
124 VampJson::BufferSerialisation::Text);
125
126 if (!rr.success) {
127
128 j = VampJson::fromError(rr.errorText, rr.type);
129
130 } else {
131
132 switch (rr.type) {
133
134 case RRType::List:
135 j = VampJson::fromVampResponse_List(rr.listResponse);
136 break;
137 case RRType::Load:
138 j = VampJson::fromVampResponse_Load(rr.loadResponse, m_mapper);
139 break;
140 case RRType::Configure:
141 j = VampJson::fromVampResponse_Configure(rr.configurationResponse,
142 m_mapper);
143 break;
144 case RRType::Process:
145 j = VampJson::fromVampResponse_Process
146 (rr.processResponse, m_mapper, serialisation);
147 break;
148 case RRType::Finish:
149 j = VampJson::fromVampResponse_Finish
150 (rr.finishResponse, m_mapper, serialisation);
151 break;
152 case RRType::NotValid:
153 break;
154 }
155 }
156
157 return j.dump();
158 }
159
160 Vamp::HostExt::ListResponse 76 Vamp::HostExt::ListResponse
161 VamPipePluginLibrary::listPluginData() const 77 VamPipePluginLibrary::listPluginData() const
162 { 78 {
163 Vamp::HostExt::ListResponse resp; 79 Vamp::HostExt::ListResponse resp;
164 for (auto a: m_adapters) { 80 for (auto a: m_adapters) {
208 VamPipePluginLibrary::processRawImpl(int pluginHandle, 124 VamPipePluginLibrary::processRawImpl(int pluginHandle,
209 const float *const *inputBuffers, 125 const float *const *inputBuffers,
210 int sec, 126 int sec,
211 int nsec) 127 int nsec)
212 { 128 {
213 RequestOrResponse response;
214 response.direction = RequestOrResponse::Response;
215 response.type = RRType::Process;
216
217 try { 129 try {
218 if (!m_mapper.isConfigured(pluginHandle)) { 130 if (!m_mapper.isConfigured(pluginHandle)) {
219 throw runtime_error("plugin has not been configured"); 131 throw runtime_error("plugin has not been configured");
220 } 132 }
221 133
222 Vamp::Plugin *plugin = m_mapper.handleToPlugin(pluginHandle); 134 Vamp::Plugin *plugin = m_mapper.handleToPlugin(pluginHandle);
223 Vamp::RealTime timestamp(sec, nsec); 135 Vamp::RealTime timestamp(sec, nsec);
224 136
225 response.processResponse.plugin = plugin; 137 Vamp::HostExt::ProcessResponse resp;
226 response.processResponse.features = plugin->process(inputBuffers, timestamp); 138 resp.plugin = plugin;
227 response.success = true; 139 resp.features = plugin->process(inputBuffers, timestamp);
228 140
229 m_useBase64 = true; 141 m_useBase64 = true;
230 142
231 return writeResponse(response); 143 return VampJson::fromVampResponse_Process
144 (resp, m_mapper,
145 VampJson::BufferSerialisation::Base64)
146 .dump();
232 147
233 } catch (const std::exception &e) { 148 } catch (const std::exception &e) {
234 return VampJson::fromException(e, RRType::Process).dump(); 149 return VampJson::fromException(e, RRType::Process)
150 .dump();
235 } 151 }
236 } 152 }
237 153
238 string 154 string
239 VamPipePluginLibrary::requestJsonImpl(string req) 155 VamPipePluginLibrary::requestJsonImpl(string req)
240 { 156 {
241 RequestOrResponse request; 157 Json j = convertRequestJson(req);
242 158
159 RRType type;
243 try { 160 try {
244 request = readRequest(req); 161 type = VampJson::getRequestResponseType(j);
245 } catch (const std::exception &e) { 162 } catch (const std::exception &e) {
246 return VampJson::fromException(e, RRType::NotValid).dump(); 163 return VampJson::fromException(e, RRType::NotValid)
247 } 164 .dump();
248 165 }
249 RequestOrResponse response; 166
250 response.direction = RequestOrResponse::Response; 167 VampJson::BufferSerialisation serialisation =
251 response.type = request.type; 168 (m_useBase64 ?
252 169 VampJson::BufferSerialisation::Base64 :
170 VampJson::BufferSerialisation::Text);
171
172 Json rj;
173
253 try { 174 try {
254 switch (request.type) { 175 switch (type) {
255 176
256 case RRType::List: 177 case RRType::List:
257 response.listResponse = listPluginData(); 178 rj = VampJson::fromVampResponse_List(listPluginData());
258 response.success = true; 179 break;
259 break; 180
260 181 case RRType::Load:
261 case RRType::Load: 182 {
262 response.loadResponse = loadPlugin(request.loadRequest); 183 auto req = VampJson::toVampRequest_Load(j);
263 if (response.loadResponse.plugin) { 184 auto resp = loadPlugin(req);
264 m_mapper.addPlugin(response.loadResponse.plugin); 185 if (resp.plugin) {
265 response.success = true; 186 m_mapper.addPlugin(resp.plugin);
266 } 187 }
267 break; 188 rj = VampJson::fromVampResponse_Load(resp, m_mapper);
189 break;
190 }
191
192 case RRType::Configure:
193 {
194 auto req = VampJson::toVampRequest_Configure(j, m_mapper);
195 auto h = m_mapper.pluginToHandle(req.plugin);
196 if (m_mapper.isConfigured(h)) {
197 throw runtime_error("plugin has already been configured");
198 }
199
200 auto resp = configurePlugin(req);
201 if (!resp.outputs.empty()) {
202 m_mapper.markConfigured(h,
203 req.configuration.channelCount,
204 req.configuration.blockSize);
205 }
206
207 rj = VampJson::fromVampResponse_Configure(resp, m_mapper);
208 break;
209 }
210
211 case RRType::Process:
212 {
213 VampJson::BufferSerialisation serialisation;
214
215 auto req = VampJson::toVampRequest_Process(j, m_mapper,
216 serialisation);
217
218 auto h = m_mapper.pluginToHandle(req.plugin);
219 if (!m_mapper.isConfigured(h)) {
220 throw runtime_error("plugin has not been configured");
221 }
222
223 int channels = int(req.inputBuffers.size());
224 if (channels != m_mapper.getChannelCount(h)) {
225 throw runtime_error("wrong number of channels supplied to process");
226 }
227
228 if (serialisation == VampJson::BufferSerialisation::Base64) {
229 m_useBase64 = true;
230 }
231
232 const float **fbuffers = new const float *[channels];
233 for (int i = 0; i < channels; ++i) {
234 if (int(req.inputBuffers[i].size()) != m_mapper.getBlockSize(h)) {
235 delete[] fbuffers;
236 throw runtime_error("wrong block size supplied to process");
237 }
238 fbuffers[i] = req.inputBuffers[i].data();
239 }
240
241 Vamp::HostExt::ProcessResponse resp;
242 resp.plugin = req.plugin;
243 resp.features = req.plugin->process(fbuffers, req.timestamp);
244 delete[] fbuffers;
245
246 rj = VampJson::fromVampResponse_Process(resp, m_mapper, serialisation);
247 break;
248 }
249
250 case RRType::Finish:
251 {
252 auto req = VampJson::toVampRequest_Finish(j, m_mapper);
253 auto h = m_mapper.pluginToHandle(req.plugin);
254 if (!m_mapper.isConfigured(h)) {
255 throw runtime_error("plugin has not been configured");
256 }
257
258 Vamp::HostExt::ProcessResponse resp;
259 resp.plugin = req.plugin;
260 resp.features = req.plugin->getRemainingFeatures();
261
262 rj = VampJson::fromVampResponse_Finish(resp, m_mapper, serialisation);
268 263
269 case RRType::Configure:
270 {
271 auto &creq = request.configurationRequest;
272 auto h = m_mapper.pluginToHandle(creq.plugin);
273 if (m_mapper.isConfigured(h)) {
274 throw runtime_error("plugin has already been configured");
275 }
276
277 response.configurationResponse = configurePlugin(creq);
278
279 if (!response.configurationResponse.outputs.empty()) {
280 m_mapper.markConfigured
281 (h, creq.configuration.channelCount, creq.configuration.blockSize);
282 response.success = true;
283 }
284 break;
285 }
286
287 case RRType::Process:
288 {
289 auto &preq = request.processRequest;
290 auto h = m_mapper.pluginToHandle(preq.plugin);
291 if (!m_mapper.isConfigured(h)) {
292 throw runtime_error("plugin has not been configured");
293 }
294
295 int channels = int(preq.inputBuffers.size());
296 if (channels != m_mapper.getChannelCount(h)) {
297 throw runtime_error("wrong number of channels supplied to process");
298 }
299
300 const float **fbuffers = new const float *[channels];
301 for (int i = 0; i < channels; ++i) {
302 if (int(preq.inputBuffers[i].size()) != m_mapper.getBlockSize(h)) {
303 delete[] fbuffers;
304 throw runtime_error("wrong block size supplied to process");
305 }
306 fbuffers[i] = preq.inputBuffers[i].data();
307 }
308
309 response.processResponse.plugin = preq.plugin;
310 response.processResponse.features =
311 preq.plugin->process(fbuffers, preq.timestamp);
312 response.success = true;
313
314 delete[] fbuffers;
315 break;
316 }
317
318 case RRType::Finish:
319 {
320 response.finishResponse.plugin = request.finishRequest.plugin;
321 response.finishResponse.features =
322 request.finishRequest.plugin->getRemainingFeatures();
323
324 // We do not delete the plugin here -- we need it in the
325 // mapper when converting the features. It gets deleted
326 // below, after the writeResponse() call.
327
328 response.success = true;
329 break;
330 }
331
332 case RRType::NotValid:
333 break;
334 }
335
336 string rstr = writeResponse(response);
337
338 if (request.type == RRType::Finish) {
339 auto h = m_mapper.pluginToHandle(request.finishRequest.plugin);
340 m_mapper.removePlugin(h); 264 m_mapper.removePlugin(h);
341 delete request.finishRequest.plugin; 265 delete req.plugin;
342 } 266 break;
343 267 }
344 return rstr; 268
345 269 case RRType::NotValid:
270 rj = VampJson::fromError("invalid request", type);
271 break;
272 }
273
346 } catch (const std::exception &e) { 274 } catch (const std::exception &e) {
347 return VampJson::fromException(e, request.type).dump(); 275 rj = VampJson::fromException(e, type);
348 } 276 }
349 } 277
350 278 return rj.dump();
351 } 279 }
352 280
281 }
282